c++: most vexing parse and braced CTAD [PR89062]
Here grokdeclarator is emitting the error
error: class template placeholder ‘Foo’ not permitted in this context
during the tentative (and ultimately futile) parse of 'x' as a function
declaration. This happens because when parsing 'Foo{1}',
cp_parser_parameter_declaration yields a parameter declaration with no
declarator and whose type is a CTAD placeholder, and stops short of
consuming the '{'. The caller cp_parser_parameter_declaration_list then
calls grokdeclarator on this declarator, hence the error, and soon
thereafter we abort this tentative parse since the next token '{'
doesn't make sense in the context of a parameter list.
Note that we don't have this issue with parenthesized CTAD
Foo<int> x(Foo(1));
because in this case cp_parser_direct_declarator (called indirectly from
c_p_p_d) consumes the '(' and returns cp_error_declarator instead of a
NULL declarator (and also simulates a parse error), and grokdeclarator
exits early for this declarator without emitting any error.
Since grokdeclarator doesn't take a 'complain' parameter, to fix this we
need to avoid calling grokdeclarator in this situation. To that end
this patch makes c_p_p_d simulate an error when a construct is a CTAD
expression and definitely not a parameter declaration, so that c_p_p_d_l
can avoid calling grokdeclarator by checking for this simulated error.
Alternatively we could keep all this logic inside c_p_p_d_l and not
touch c_p_p_d at all, but this approach seems slightly less adhoc.
PR c++/89062
gcc/cp/ChangeLog:
* parser.c (cp_parser_parameter_declaration_list): Don't call
grokdeclarator if cp_parser_error_occurred.
(cp_parser_parameter_declaration): Simulate an error if we see
the beginning of a CTAD form, i.e. if we see an opening brace
after the decl-specifier-seq and the type is a CTAD placeholder.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/class-deduction97.C: New test.