diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-06 16:14:19 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-07 08:51:12 -0500 |
commit | 82aee6dd61e2a5b4e4b124f896c8403169688f41 (patch) | |
tree | d45df0fc330ed4a44c5ac31be47f4b660b0b37e5 | |
parent | 3c7a03bc360c3511fae3747a71e579e9fd0824f9 (diff) | |
download | gcc-82aee6dd61e2a5b4e4b124f896c8403169688f41.zip gcc-82aee6dd61e2a5b4e4b124f896c8403169688f41.tar.gz gcc-82aee6dd61e2a5b4e4b124f896c8403169688f41.tar.bz2 |
c++: Fix ICE on nonsense requires-clause.
Here we were swallowing all the syntax errors by parsing tentatively, and
returning error_mark_node without ever actually giving an error. Fixed by
using save_tokens/rollback_tokens instead.
PR c++/92517
* parser.c (cp_parser_constraint_primary_expression): Do the main
parse non-tentatively.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-syntax1.C | 9 |
3 files changed, 22 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1c8af80..df7d2ca 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-06 Jason Merrill <jason@redhat.com> + + PR c++/92517 + * parser.c (cp_parser_constraint_primary_expression): Do the main + parse non-tentatively. + 2020-02-06 Marek Polacek <polacek@redhat.com> PR c++/93597 - ICE with lambda in operator function. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e0f7230..d4c9523 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -27478,7 +27478,7 @@ cp_parser_constraint_primary_expression (cp_parser *parser, bool lambda_p) return e; } - cp_parser_parse_tentatively (parser); + cp_lexer_save_tokens (parser->lexer); cp_id_kind idk; location_t loc = input_location; cp_expr expr = cp_parser_primary_expression (parser, @@ -27494,19 +27494,16 @@ cp_parser_constraint_primary_expression (cp_parser *parser, bool lambda_p) /* The primary-expression could be part of an unenclosed non-logical compound expression. */ pce = cp_parser_constraint_requires_parens (parser, lambda_p); - if (pce != pce_ok) - cp_parser_simulate_error (parser); - else - expr = finish_constraint_primary_expr (expr); } - if (cp_parser_parse_definitely (parser)) - return expr; - if (expr == error_mark_node) - return error_mark_node; + if (pce == pce_ok) + { + cp_lexer_commit_tokens (parser->lexer); + return finish_constraint_primary_expr (expr); + } /* Retry the parse at a lower precedence. If that succeeds, diagnose the error, but return the expression as if it were valid. */ - gcc_assert (pce != pce_ok); + cp_lexer_rollback_tokens (parser->lexer); cp_parser_parse_tentatively (parser); if (pce == pce_maybe_operator) expr = cp_parser_assignment_expression (parser, NULL, false, false); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-syntax1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-syntax1.C new file mode 100644 index 0000000..0a47682 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-syntax1.C @@ -0,0 +1,9 @@ +// PR c++/92517 +// { dg-do compile { target concepts } } + +template <typename T> +concept C = true; + +template<int I> +requires C decltype<I> // { dg-error "" } +void f() {} |