Message ID | 20200416233319.3394053-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Hard error with tentative parse of declaration [PR88754] | expand |
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" } > +} >
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 --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" } +}