From 91f9108f1bd90c307daadfb4876258ec57cb746b Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 23 Mar 2018 01:18:48 +0000 Subject: [PATCH] Disable auto_is_implicit_function_template_parm_p while parsing attributes We don't want functions to become implicit templates just because of random uses of auto in unexpected places. Disabling the special handling of auto while parsing attributes, for example, makes for more sensible errors. for gcc/cp/ChangeLog PR c++/84610 PR c++/84642 PR c++/84942 * cp-tree.h (temp_override): New template class, generalizing a cleanup that was only used... * parser.c (cp_parser_parameter_declaration_clause): ... here for auto_is_implicit_function_template_parm_p. (cp_parser_gnu_attributes_opt): Use it here as well. (cp_parser_std_attribute): Likewise. From-SVN: r258790 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/cp-tree.h | 19 +++++++++++++++++++ gcc/cp/parser.c | 18 ++++++++---------- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f9e7a57..5dae29d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2018-03-22 Alexandre Oliva + + PR c++/84610 + PR c++/84642 + PR c++/84942 + * cp-tree.h (temp_override): New template class, generalizing + a cleanup that was only used... + * parser.c (cp_parser_parameter_declaration_clause): + ... here for auto_is_implicit_function_template_parm_p. + (cp_parser_gnu_attributes_opt): Use it here as well. + (cp_parser_std_attribute): Likewise. + 2018-03-22 Marek Polacek PR c++/84854 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c07aaa5..c8f4bc4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1657,6 +1657,25 @@ struct warning_sentinel ~warning_sentinel() { flag = val; } }; +/* RAII sentinel that saves the value of a variable, optionally + overrides it right away, and restores its value when the sentinel + id destructed. */ + +template +class temp_override +{ + T& overridden_variable; + T saved_value; +public: + temp_override(T& var) : overridden_variable (var), saved_value (var) {} + temp_override(T& var, T overrider) + : overridden_variable (var), saved_value (var) + { + overridden_variable = overrider; + } + ~temp_override() { overridden_variable = saved_value; } +}; + /* The cached class binding level, from the most recently exited class, or NULL if none. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6dcfae1..3461929 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21196,16 +21196,8 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) bool ellipsis_p; bool is_error; - struct cleanup { - cp_parser* parser; - int auto_is_implicit_function_template_parm_p; - ~cleanup() { - parser->auto_is_implicit_function_template_parm_p - = auto_is_implicit_function_template_parm_p; - } - } cleanup = { parser, parser->auto_is_implicit_function_template_parm_p }; - - (void) cleanup; + temp_override cleanup + (parser->auto_is_implicit_function_template_parm_p); if (!processing_specialization && !processing_template_parmlist @@ -24968,6 +24960,9 @@ cp_parser_gnu_attributes_opt (cp_parser* parser) { tree attributes = NULL_TREE; + temp_override cleanup + (parser->auto_is_implicit_function_template_parm_p, false); + while (true) { cp_token *token; @@ -25159,6 +25154,9 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns) tree attribute, attr_id = NULL_TREE, arguments; cp_token *token; + temp_override cleanup + (parser->auto_is_implicit_function_template_parm_p, false); + /* First, parse name of the attribute, a.k.a attribute-token. */ token = cp_lexer_peek_token (parser->lexer); -- 2.7.4