On 4/16/20 7:33 PM, Patrick Palka wrote:
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.
Passes 'make check-c++', does this look OK to commit after bootstrap/regtesting?
gcc/cp/ChangeLog:
PR c++/88754
* parser. (cp_parser_check_template_parameters): Before issiung a hard
error, first try simulating an error instead.
OK.
gcc/testsuite/ChangeLog:
PR c++/88754
* g++.dg/parse/ambig10.C: New test.
---
gcc/cp/parser.c | 4 ++++
gcc/testsuite/g++.dg/parse/ambig10.C | 20 ++++++++++++++++++++
2 files changed, 24 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/parse/ambig10.C
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e037e7d8c8e..47e3f2bbd3d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -28531,6 +28531,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:
diff --git a/gcc/testsuite/g++.dg/parse/ambig10.C b/gcc/testsuite/g++.dg/parse/ambig10.C
new file mode 100644
index 00000000000..42b04b16923
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/ambig10.C
@@ -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" }
+}