diff options
author | Jason Merrill <jason@redhat.com> | 2015-12-06 23:35:14 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-12-06 23:35:14 -0500 |
commit | 1bf2ca0b75a3b6ce72ab4065dbc10b7f80413d4b (patch) | |
tree | afce09c0b85c9dae374e599eab13a28b6d6b0510 | |
parent | ca8e4b87ad6da53a0e8c17227f7ef82e38df66fb (diff) | |
download | gcc-1bf2ca0b75a3b6ce72ab4065dbc10b7f80413d4b.zip gcc-1bf2ca0b75a3b6ce72ab4065dbc10b7f80413d4b.tar.gz gcc-1bf2ca0b75a3b6ce72ab4065dbc10b7f80413d4b.tar.bz2 |
Fix parse/no-type-defn1.C with -std=c++1z.
* parser.c (struct tentative_firewall): New.
(cp_parser_template_id, cp_parser_decltype_expr): Use it.
From-SVN: r231354
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/no-type-defn1.C | 2 |
3 files changed, 52 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ca9b97c..c4daf75 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-12-06 Jason Merrill <jason@redhat.com> + * parser.c (struct tentative_firewall): New. + (cp_parser_template_id, cp_parser_decltype_expr): Use it. + * parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses tree_check_value. * parser.c (cp_parser_decltype): Use tree_check_value. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ce5a21a..3e90f11 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4326,6 +4326,43 @@ cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start, cp_lexer_purge_tokens_after (parser->lexer, start); } +/* Like the above functions, but let the user modify the tokens. Used by + CPP_DECLTYPE and CPP_TEMPLATE_ID, where we are saving the side-effects for + later parses, so it makes sense to localize the effects of + cp_parser_commit_to_tentative_parse. */ + +struct tentative_firewall +{ + cp_parser *parser; + bool set; + + tentative_firewall (cp_parser *p): parser(p) + { + /* If we're currently parsing tentatively, start a committed level as a + firewall and then an inner tentative parse. */ + if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser))) + { + cp_parser_parse_tentatively (parser); + cp_parser_commit_to_topmost_tentative_parse (parser); + cp_parser_parse_tentatively (parser); + } + } + + ~tentative_firewall() + { + if (set) + { + /* Finish the inner tentative parse and the firewall, propagating any + uncommitted error state to the outer tentative parse. */ + bool err = cp_parser_error_occurred (parser); + cp_parser_parse_definitely (parser); + cp_parser_parse_definitely (parser); + if (err) + cp_parser_simulate_error (parser); + } + } +}; + /* Parse a GNU statement-expression, i.e. ({ stmts }), except for the enclosing parentheses. */ @@ -12921,6 +12958,11 @@ cp_parser_decltype_expr (cp_parser *parser, cp_token *id_expr_start_token; tree expr; + /* Since we're going to preserve any side-effects from this parse, set up a + firewall to protect our callers from cp_parser_commit_to_tentative_parse + in the expression. */ + tentative_firewall firewall (parser); + /* First, try parsing an id-expression. */ id_expr_start_token = cp_lexer_peek_token (parser->lexer); cp_parser_parse_tentatively (parser); @@ -14687,6 +14729,11 @@ cp_parser_template_id (cp_parser *parser, return templ; } + /* Since we're going to preserve any side-effects from this parse, set up a + firewall to protect our callers from cp_parser_commit_to_tentative_parse + in the template arguments. */ + tentative_firewall firewall (parser); + /* If we find the sequence `[:' after a template-name, it's probably a digraph-typo for `< ::'. Substitute the tokens and check if we can parse correctly the argument list. */ diff --git a/gcc/testsuite/g++.dg/parse/no-type-defn1.C b/gcc/testsuite/g++.dg/parse/no-type-defn1.C index 9e89957..a8d6ad8 100644 --- a/gcc/testsuite/g++.dg/parse/no-type-defn1.C +++ b/gcc/testsuite/g++.dg/parse/no-type-defn1.C @@ -3,3 +3,5 @@ template<typename> struct A { }; A< struct B { }* >::SomeNonSense // { dg-error "types may not be defined" } int y; + +// { dg-prune-output "SomeNonSense" } |