Friendly ping. Thanks! On 17 Sep 2024, at 14:14, Simon Martin wrote:
> The invalid test case in this PR highlights a bad interaction between > the tentative_firewall and error recovery in cp_parser_decltype: the > firewall makes cp_parser_skip_to_closing_parenthesis a no-op, and the > parser does not make any progress, running "forever". > > This patch calls cp_parser_commit_to_tentative_parse before initiating > error recovery. > > Successfully tested on x86_64-pc-linux-gnu. > > PR c++/114858 > > gcc/cp/ChangeLog: > > * parser.cc (cp_parser_decltype): Commit tentative parse before > initiating error recovery. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/decltype10.C: Adjust test expectation. > * g++.dg/cpp2a/pr114858.C: New test. > --- > gcc/cp/parser.cc | 3 +++ > gcc/testsuite/g++.dg/cpp0x/decltype10.C | 2 ++ > gcc/testsuite/g++.dg/cpp2a/pr114858.C | 25 > +++++++++++++++++++++++++ > 3 files changed, 30 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr114858.C > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index 4dd9474cf60..3a7c5ffe4c8 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -17508,6 +17508,9 @@ cp_parser_decltype (cp_parser *parser) > /* Parse to the closing `)'. */ > if (expr == error_mark_node || !parens.require_close (parser)) > { > + /* Commit to the tentative_firewall so we actually skip to the > closing > + parenthesis. */ > + cp_parser_commit_to_tentative_parse (parser); > cp_parser_skip_to_closing_parenthesis (parser, true, false, > /*consume_paren=*/true); > expr = error_mark_node; > diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype10.C > b/gcc/testsuite/g++.dg/cpp0x/decltype10.C > index fe7247269f5..bd606e325d4 100644 > --- a/gcc/testsuite/g++.dg/cpp0x/decltype10.C > +++ b/gcc/testsuite/g++.dg/cpp0x/decltype10.C > @@ -7,3 +7,5 @@ template<int> struct A > }; > > template<int N> int A<N>::i(decltype (A::i; // { dg-error "expected" > } > + > +// { dg-excess-errors "" } > diff --git a/gcc/testsuite/g++.dg/cpp2a/pr114858.C > b/gcc/testsuite/g++.dg/cpp2a/pr114858.C > new file mode 100644 > index 00000000000..6ffde4c3a2c > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/pr114858.C > @@ -0,0 +1,25 @@ > +// PR c++/114858 > +// { dg-do compile { target c++20 } } > +// { dg-timeout 2 } > + > +template <class F> void g(F); > +template <class... A> > +auto h(A &&... a) -> decltype( > + decltype(g< // { dg-error "expected primary-expression" } > + decltype(g<decltype(g<decltype(g<decltype(g<decltype(g< > + decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g< > + decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g< > + decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g< > + decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g< > + decltype(g<decltype(g< > + decltype()>)(a)...) > +{ > + h([] {}); > +} > + > +int main() { > + h(); > + return 0; > +} > + > +// { dg-excess-errors "" } > -- > 2.44.0