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 f9e7a57ec03dffb235c7916a267f2e1a23cfc058..5dae29d23a14f899b0b7ba45a0dc7340ab1a780a 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 c07aaa5781ac4225595f63d4759bdd527aa50279..c8f4bc43fa3c39597664b5b66603fcefc7ab0137 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 6dcfae125b7bff0c34c31baa85dfbb41f697623a..34619293120b6e2e3c1dd0a66587c32a89b924c1 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);