c++: Hard error with tentative parse of declaration [PR88754]
authorPatrick Palka <ppalka@redhat.com>
Thu, 16 Apr 2020 20:45:15 +0000 (16:45 -0400)
committerPatrick Palka <ppalka@redhat.com>
Fri, 17 Apr 2020 17:58:52 +0000 (13:58 -0400)
In the testcase for this PR, we try to parse the statement

  A(value<0>());

first tentatively as a declaration (with a parenthesized declarator), and during
this tentative parse we end up issuing a hard error from
cp_parser_check_template_parameters about its invalidness as a declaration.

Rather than issuing a hard error, it seems we should instead simulate an error
since we're parsing tentatively.  This would then allow cp_parser_statement to
recover and successfully parse the statement as an expression-statement instead.

gcc/cp/ChangeLog:

PR c++/88754
* parser.c (cp_parser_check_template_parameters): Before issuing a hard
error, first try simulating an error instead.

gcc/testsuite/ChangeLog:

PR c++/88754
* g++.dg/parse/ambig10.C: New test.

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/ambig10.C [new file with mode: 0644]

index 8410ff1..465f290 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-17  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/88754
+       * parser.c (cp_parser_check_template_parameters): Before issuing a hard
+       error, first try simulating an error instead.
+
 2020-04-17  Jakub Jelinek  <jakub@redhat.com>
 
        PR other/94629
index 7be4a8f..d2f3f85 100644 (file)
@@ -28530,6 +28530,10 @@ cp_parser_check_template_parameters (cp_parser* parser,
   if (!template_id_p
       && parser->num_template_parameter_lists == num_templates + 1)
     return true;
+
+  if (cp_parser_simulate_error (parser))
+    return false;
+
   /* If there are more template classes than parameter lists, we have
      something like:
 
index 15f5cb2..b80e7da 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-17  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/88754
+       * g++.dg/parse/ambig10.C: New test.
+
 2020-04-17  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/94090
diff --git a/gcc/testsuite/g++.dg/parse/ambig10.C b/gcc/testsuite/g++.dg/parse/ambig10.C
new file mode 100644 (file)
index 0000000..42b04b1
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/88754
+// { dg-do compile }
+
+struct A
+{
+  A(int);
+  void foo();
+};
+
+template<int N> int value() { return N; }
+
+void bar()
+{
+  A(value<0>()).foo();
+  A(value<0>());
+  (A(value<0>())).foo();
+
+  A value<0>; // { dg-error "invalid declaration" }
+  A value<0>(); // { dg-error "invalid declaration" }
+}