From b39913594a6a01816975e61ebff0d168124ebf6c Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 1 Dec 2015 15:18:56 -0500 Subject: [PATCH 19/20] FIXME: fix g++.dg/cpp0x/nsdmi-template14.C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Within g++.dg/cpp0x/nsdmi-template14.C, the previous token within a new expr can have been purged, so don't try to use it. 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) Reason for the lack of a caret is that cp_lexer_previous_token is returning a purged token hence the location is 0: (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 is hitting line 726 here: 722 static inline cp_token_position 723 cp_lexer_previous_token_position (cp_lexer *lexer) 724 { 725 if (lexer->next_token == &eof_token) 726 return lexer->last_token - 1; 727 else 728 return cp_lexer_token_position (lexer, true); 729 } (gdb) p *(lexer->last_token - 1) $56 = {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 = }} Detect purged tokens here; don't try to use them. Qn: why is it purged? --- 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 1af12ef..9e82e66 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7912,9 +7912,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