diff mbox series

c++: Hard error with tentative parse of declaration [PR88754]

Message ID 20200416233319.3394053-1-ppalka@redhat.com
State New
Headers show
Series c++: Hard error with tentative parse of declaration [PR88754] | expand

Commit Message

Patrick Palka April 16, 2020, 11:33 p.m. UTC
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.

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

Comments

Jason Merrill April 17, 2020, 4:45 p.m. UTC | #1
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" }
> +}
>
Jakub Jelinek April 17, 2020, 4:54 p.m. UTC | #2
On Fri, Apr 17, 2020 at 12:45:37PM -0400, Jason Merrill via Gcc-patches wrote:
> 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

s/\. /.c/;s/issiung/issuing/

> > 	error, first try simulating an error instead.

	Jakub
diff mbox series

Patch

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" }
+}