c++: fix parsing with auto(x) at block scope [PR112482]
This is sort of like r14-5514, but at block scope. Consider struct A { A(int, int); }; void g (int a) { A bar(auto(a), 42); // not a fn decl } where we emit error: 'auto' parameter not permitted in this context which is bogus -- bar doesn't declare a function, so the auto is OK, but we don't know it till we've seen the second argument. The error comes from grokdeclarator invoked just after we've parsed the auto(a). A possible approach seems to be to delay the auto parameter checking and only check once we know we are indeed dealing with a function declaration. For tparms, we should still emit the error right away. PR c++/112482 gcc/cp/ChangeLog: * decl.cc (grokdeclarator): Do not issue the auto parameter error while tentatively parsing a function parameter. * parser.cc (cp_parser_parameter_declaration_clause): Check it here. gcc/testsuite/ChangeLog: * g++.dg/cpp23/auto-fncast15.C: New test.
This commit is contained in:
parent
5fa27d9f8c
commit
1ae7126989
3 changed files with 47 additions and 4 deletions
|
@ -14203,6 +14203,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
tree auto_node = type_uses_auto (type);
|
||||
if (auto_node && !(cxx_dialect >= cxx17 && template_parm_flag))
|
||||
{
|
||||
bool err_p = true;
|
||||
if (cxx_dialect >= cxx14)
|
||||
{
|
||||
if (decl_context == PARM && AUTO_IS_DECLTYPE (auto_node))
|
||||
|
@ -14221,13 +14222,21 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
"abbreviated function template");
|
||||
inform (DECL_SOURCE_LOCATION (c), "%qD declared here", c);
|
||||
}
|
||||
else
|
||||
else if (decl_context == CATCHPARM || template_parm_flag)
|
||||
error_at (typespec_loc,
|
||||
"%<auto%> parameter not permitted in this context");
|
||||
else
|
||||
/* Do not issue an error while tentatively parsing a function
|
||||
parameter: for T t(auto(a), 42);, when we just saw the 1st
|
||||
parameter, we don't know yet that this construct won't be
|
||||
a function declaration. Defer the checking to
|
||||
cp_parser_parameter_declaration_clause. */
|
||||
err_p = false;
|
||||
}
|
||||
else
|
||||
error_at (typespec_loc, "parameter declared %<auto%>");
|
||||
type = error_mark_node;
|
||||
if (err_p)
|
||||
type = error_mark_node;
|
||||
}
|
||||
|
||||
/* A parameter declared as an array of T is really a pointer to T.
|
||||
|
|
|
@ -25102,8 +25102,21 @@ cp_parser_parameter_declaration_clause (cp_parser* parser,
|
|||
committed yet, nor should we. Pushing here will detect the error
|
||||
of redefining a parameter. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
|
||||
for (tree p : pending_decls)
|
||||
pushdecl (p);
|
||||
{
|
||||
for (tree p : pending_decls)
|
||||
pushdecl (p);
|
||||
|
||||
/* Delayed checking of auto parameters. */
|
||||
if (!parser->auto_is_implicit_function_template_parm_p
|
||||
&& cxx_dialect >= cxx14)
|
||||
for (tree p = parameters; p; p = TREE_CHAIN (p))
|
||||
if (type_uses_auto (TREE_TYPE (TREE_VALUE (p))))
|
||||
{
|
||||
error_at (location_of (TREE_VALUE (p)),
|
||||
"%<auto%> parameter not permitted in this context");
|
||||
TREE_TYPE (TREE_VALUE (p)) = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish the parameter list. */
|
||||
if (!ellipsis_p)
|
||||
|
|
21
gcc/testsuite/g++.dg/cpp23/auto-fncast15.C
Normal file
21
gcc/testsuite/g++.dg/cpp23/auto-fncast15.C
Normal file
|
@ -0,0 +1,21 @@
|
|||
// PR c++/112482
|
||||
// { dg-do compile { target c++23 } }
|
||||
// { dg-options "-Wno-vexing-parse" }
|
||||
|
||||
void foo (auto i, auto j);
|
||||
|
||||
struct A {
|
||||
A(int,int);
|
||||
};
|
||||
|
||||
void
|
||||
g (int a)
|
||||
{
|
||||
A b1(auto(42), auto(42));
|
||||
A b2(auto(a), auto(42));
|
||||
A b3(auto(42), auto(a));
|
||||
A b4(auto(a), // { dg-error "13:'auto' parameter" }
|
||||
auto(a2)); // { dg-error "13:'auto' parameter" }
|
||||
int v1(auto(42));
|
||||
int fn1(auto(a)); // { dg-error "16:'auto' parameter" }
|
||||
}
|
Loading…
Add table
Reference in a new issue