Disable auto_is_implicit_function_template_parm_p while parsing attributes
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 23 Mar 2018 01:18:48 +0000 (01:18 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 23 Mar 2018 01:18:48 +0000 (01:18 +0000)
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
gcc/cp/cp-tree.h
gcc/cp/parser.c

index f9e7a57..5dae29d 100644 (file)
@@ -1,3 +1,15 @@
+2018-03-22  Alexandre Oliva <aoliva@redhat.com>
+
+       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  <polacek@redhat.com>
 
        PR c++/84854
index c07aaa5..c8f4bc4 100644 (file)
@@ -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 <typename T>
+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.  */
 
index 6dcfae1..3461929 100644 (file)
@@ -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<bool> 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<bool> 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<bool> 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);