From f2f38b92c8035820b5225b7d91180de1cc439445 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 1 Dec 2015 15:18:56 -0500 Subject: [PATCH 02/10] Fix g++.dg/cpp0x/nsdmi-template14.C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building new-expressions, we use cp_lexer_previous_token and access its location to get the final position in the source range. Within g++.dg/cpp0x/nsdmi-template14.C, the previous token within a new expr can have been purged, leading to UNKNOWN_LOCATION. g++.dg/cpp0x/nsdmi-template14.C:11:10: error: recursive instantiation of non-static data member initializer for ‘B<1>::p’ B* p = new B; (note the lack of caret) (gdb) p *end_tok $54 = {type = CPP_GREATER, keyword = RID_MAX, flags = 0 '\000', pragma_kind = PRAGMA_NONE, implicit_extern_c = 0, error_reported = 0, purged_p = 1, location = 0, u = {tree_check_value = 0x0, value = }} This patch adds bulletproofing to detect purged tokens, and avoid using them. Alternatively, is it OK to access purged tokens for this kind of thing? If so, would it make more sense to instead leave their locations untouched when purging them? The patch also updates the location of a dg-error directive in the testcase to reflect improved location information. gcc/cp/ChangeLog: * parser.c (cp_parser_new_expression): Avoid accessing purged tokens when getting end of location range. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template14.C: Move dg-error directive. --- gcc/cp/parser.c | 10 +++++++--- gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bdb3f7d..50b3ad9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7946,9 +7946,13 @@ cp_parser_new_expression (cp_parser* parser) with caret == start at the start of the "new" token, and the end at the end of the final token we consumed. */ cp_token *end_tok = cp_lexer_previous_token (parser->lexer); - location_t end_loc = get_finish (end_tok->location); - location_t combined_loc = make_location (start_loc, start_loc, end_loc); - + location_t combined_loc = start_loc; + if (!end_tok->purged_p) + { + location_t end_loc = get_finish (end_tok->location); + gcc_assert (end_loc); + combined_loc = make_location (start_loc, start_loc, end_loc); + } /* Create a representation of the new-expression. */ ret = build_new (&placement, type, nelts, &initializer, global_scope_p, tf_warning_or_error); diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C index 9cb01f1..47f5b63 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C @@ -8,10 +8,10 @@ template struct A // { dg-error "has been parsed" } template struct B { - B* p = new B; + B* p = new B; // { dg-error "recursive instantiation of non-static data" } }; -B<1> x; // { dg-error "recursive instantiation of non-static data" } +B<1> x; struct C { -- 1.8.5.3