On Mar 20, 2018, Jason Merrill <ja...@redhat.com> wrote:

>> While debugging this, I first tried another patch, that avoids the same
>> ICEs.  I thought this one was a more complete solution, and it renders
>> the other unnecessary, but I still though it might be useful to disable
>> auto->implicit_parm while parsing declarators, so as to avoid useless
>> processing.

> Better, I think, to disable it while parsing attributes; we could
> still encounter auto as a template argument in a declarator.

How about this?  Regstrapping, ok to install if it passes?

Disable auto_is_implicit_function_template_parm_p while parsing attributes

for  gcc/cp/ChangeLog

        PR c++/84610
        PR c++/84642
        * parser.c (temp_override): New template class,
        generalizing...
        (cp_parser_parameter_declaration_clause): ... this cleanup.
        Use it.
        (cp_parser_gnu_attributes_opt): Use it.
        (cp_parser_std_attribute): Use it.
---
 gcc/cp/parser.c |   36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5cc201604166..ce05615adfba 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -255,6 +255,21 @@ static bool cp_parser_omp_declare_reduction_exprs
 static void cp_finalize_oacc_routine
   (cp_parser *, tree, bool);
 
+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; }
+};
+
 /* Manifest constants.  */
 #define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
 #define CP_SAVED_TOKEN_STACK 5
@@ -21187,16 +21202,9 @@ 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);
+  (void)cleanup;
 
   if (!processing_specialization
       && !processing_template_parmlist
@@ -24959,6 +24967,10 @@ 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);
+  (void)cleanup;
+
   while (true)
     {
       cp_token *token;
@@ -25150,6 +25162,10 @@ 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);
+  (void)cleanup;
+
   /* First, parse name of the attribute, a.k.a attribute-token.  */
 
   token = cp_lexer_peek_token (parser->lexer);


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Reply via email to