aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-02-06 16:14:19 -0500
committerJason Merrill <jason@redhat.com>2020-02-07 08:51:12 -0500
commit82aee6dd61e2a5b4e4b124f896c8403169688f41 (patch)
treed45df0fc330ed4a44c5ac31be47f4b660b0b37e5
parent3c7a03bc360c3511fae3747a71e579e9fd0824f9 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/parser.c17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-syntax1.C9
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() {}