re PR c++/83824 (ICE on invalid C++ code with alignas: in chainon, at tree.c:3037)
authorJakub Jelinek <jakub@redhat.com>
Wed, 17 Jan 2018 23:42:36 +0000 (00:42 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 17 Jan 2018 23:42:36 +0000 (00:42 +0100)
PR c++/83824
* parser.c (attr_chainon): New function.
(cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq,
cp_parser_namespace_definition, cp_parser_init_declarator,
cp_parser_type_specifier_seq, cp_parser_parameter_declaration,
cp_parser_gnu_attributes_opt): Use it.
(cp_parser_member_declaration, cp_parser_objc_class_ivars,
cp_parser_objc_struct_declaration): Likewise.  Don't reset
prefix_attributes if attributes is error_mark_node.

* g++.dg/cpp0x/pr83824.C: New test.

From-SVN: r256823

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr83824.C [new file with mode: 0644]

index 5978a6495592b5c5617e16f46f67f7e976a7d914..998e0b9925eb4efb197b6dba4a24b81df713a0bf 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/83824
+       * parser.c (attr_chainon): New function.
+       (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq,
+       cp_parser_namespace_definition, cp_parser_init_declarator,
+       cp_parser_type_specifier_seq, cp_parser_parameter_declaration,
+       cp_parser_gnu_attributes_opt): Use it.
+       (cp_parser_member_declaration, cp_parser_objc_class_ivars,
+       cp_parser_objc_struct_declaration): Likewise.  Don't reset
+       prefix_attributes if attributes is error_mark_node.
+
 2018-01-17  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/78344
index 80d65a84af09292639260ae1e4df041934fde5be..222db0cad3fa33e75764675e908be43be9d2f841 100644 (file)
@@ -10908,6 +10908,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
                "attributes at the beginning of statement are ignored");
 }
 
+/* Append ATTR to attribute list ATTRS.  */
+
+static tree
+attr_chainon (tree attrs, tree attr)
+{
+  if (attrs == error_mark_node)
+    return error_mark_node;
+  if (attr == error_mark_node)
+    return error_mark_node;
+  return chainon (attrs, attr);
+}
+
 /* Parse the label for a labeled-statement, i.e.
 
    identifier :
@@ -11027,7 +11039,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes)
       else if (!cp_parser_parse_definitely (parser))
        ;
       else
-       attributes = chainon (attributes, attrs);
+       attributes = attr_chainon (attributes, attrs);
     }
 
   if (attributes != NULL_TREE)
@@ -13394,8 +13406,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
                  else
                    {
                      decl_specs->std_attributes
-                       = chainon (decl_specs->std_attributes,
-                                  attrs);
+                       = attr_chainon (decl_specs->std_attributes, attrs);
                      if (decl_specs->locations[ds_std_attribute] == 0)
                        decl_specs->locations[ds_std_attribute] = token->location;
                    }
@@ -13403,9 +13414,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
                }
            }
 
-           decl_specs->attributes
-             = chainon (decl_specs->attributes,
-                        attrs);
+         decl_specs->attributes
+           = attr_chainon (decl_specs->attributes, attrs);
          if (decl_specs->locations[ds_attribute] == 0)
            decl_specs->locations[ds_attribute] = token->location;
          continue;
@@ -18471,7 +18481,7 @@ cp_parser_namespace_definition (cp_parser* parser)
          identifier = cp_parser_identifier (parser);
 
          /* Parse any attributes specified after the identifier.  */
-         attribs = chainon (attribs, cp_parser_attributes_opt (parser));
+         attribs = attr_chainon (attribs, cp_parser_attributes_opt (parser));
        }
 
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
@@ -19633,7 +19643,7 @@ cp_parser_init_declarator (cp_parser* parser,
       decl = grokfield (declarator, decl_specifiers,
                        initializer, !is_non_constant_init,
                        /*asmspec=*/NULL_TREE,
-                       chainon (attributes, prefix_attributes));
+                       attr_chainon (attributes, prefix_attributes));
       if (decl && TREE_CODE (decl) == FUNCTION_DECL)
        cp_parser_save_default_args (parser, decl);
       cp_finalize_omp_declare_simd (parser, decl);
@@ -21007,9 +21017,9 @@ cp_parser_type_specifier_seq (cp_parser* parser,
       /* Check for attributes first.  */
       if (cp_next_tokens_can_be_attribute_p (parser))
        {
-         type_specifier_seq->attributes =
-           chainon (type_specifier_seq->attributes,
-                    cp_parser_attributes_opt (parser));
+         type_specifier_seq->attributes
+           = attr_chainon (type_specifier_seq->attributes,
+                           cp_parser_attributes_opt (parser));
          continue;
        }
 
@@ -21491,8 +21501,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
       parser->default_arg_ok_p = saved_default_arg_ok_p;
       /* After the declarator, allow more attributes.  */
       decl_specifiers.attributes
-       = chainon (decl_specifiers.attributes,
-                  cp_parser_attributes_opt (parser));
+       = attr_chainon (decl_specifiers.attributes,
+                       cp_parser_attributes_opt (parser));
 
       /* If the declarator is a template parameter pack, remember that and
         clear the flag in the declarator itself so we don't get errors
@@ -23653,13 +23663,13 @@ cp_parser_member_declaration (cp_parser* parser)
                  late_attributes = cp_parser_attributes_opt (parser);
                }
 
-             attributes = chainon (attributes, late_attributes);
+             attributes = attr_chainon (attributes, late_attributes);
 
              /* Remember which attributes are prefix attributes and
                 which are not.  */
              first_attribute = attributes;
              /* Combine the attributes.  */
-             attributes = chainon (prefix_attributes, attributes);
+             attributes = attr_chainon (prefix_attributes, attributes);
 
              /* Create the bitfield declaration.  */
              decl = grokbitfield (identifier
@@ -23715,7 +23725,7 @@ cp_parser_member_declaration (cp_parser* parser)
                 which are not.  */
              first_attribute = attributes;
              /* Combine the attributes.  */
-             attributes = chainon (prefix_attributes, attributes);
+             attributes = attr_chainon (prefix_attributes, attributes);
 
              /* If it's an `=', then we have a constant-initializer or a
                 pure-specifier.  It is not correct to parse the
@@ -23837,10 +23847,13 @@ cp_parser_member_declaration (cp_parser* parser)
          cp_finalize_oacc_routine (parser, decl, false);
 
          /* Reset PREFIX_ATTRIBUTES.  */
-         while (attributes && TREE_CHAIN (attributes) != first_attribute)
-           attributes = TREE_CHAIN (attributes);
-         if (attributes)
-           TREE_CHAIN (attributes) = NULL_TREE;
+         if (attributes != error_mark_node)
+           {
+             while (attributes && TREE_CHAIN (attributes) != first_attribute)
+               attributes = TREE_CHAIN (attributes);
+             if (attributes)
+               TREE_CHAIN (attributes) = NULL_TREE;
+           }
 
          /* If there is any qualification still in effect, clear it
             now; we will be starting fresh with the next declarator.  */
@@ -24909,7 +24922,7 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
        cp_parser_skip_to_end_of_statement (parser);
 
       /* Add these new attributes to the list.  */
-      attributes = chainon (attributes, attribute_list);
+      attributes = attr_chainon (attributes, attribute_list);
     }
 
   return attributes;
@@ -30114,7 +30127,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
             which are not.  */
          first_attribute = attributes;
          /* Combine the attributes.  */
-         attributes = chainon (prefix_attributes, attributes);
+         attributes = attr_chainon (prefix_attributes, attributes);
 
          if (width)
            /* Create the bitfield declaration.  */
@@ -30130,10 +30143,13 @@ cp_parser_objc_class_ivars (cp_parser* parser)
            objc_add_instance_variable (decl);
 
          /* Reset PREFIX_ATTRIBUTES.  */
-         while (attributes && TREE_CHAIN (attributes) != first_attribute)
-           attributes = TREE_CHAIN (attributes);
-         if (attributes)
-           TREE_CHAIN (attributes) = NULL_TREE;
+         if (attributes != error_mark_node)
+           {
+             while (attributes && TREE_CHAIN (attributes) != first_attribute)
+               attributes = TREE_CHAIN (attributes);
+             if (attributes)
+               TREE_CHAIN (attributes) = NULL_TREE;
+           }
 
          token = cp_lexer_peek_token (parser->lexer);
 
@@ -30666,8 +30682,8 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
         which are not.  */
       first_attribute = attributes;
       /* Combine the attributes.  */
-      attributes = chainon (prefix_attributes, attributes);
-      
+      attributes = attr_chainon (prefix_attributes, attributes);
+
       decl = grokfield (declarator, &declspecs,
                        NULL_TREE, /*init_const_expr_p=*/false,
                        NULL_TREE, attributes);
@@ -30676,10 +30692,13 @@ cp_parser_objc_struct_declaration (cp_parser *parser)
        return error_mark_node;
       
       /* Reset PREFIX_ATTRIBUTES.  */
-      while (attributes && TREE_CHAIN (attributes) != first_attribute)
-       attributes = TREE_CHAIN (attributes);
-      if (attributes)
-       TREE_CHAIN (attributes) = NULL_TREE;
+      if (attributes != error_mark_node)
+       {
+         while (attributes && TREE_CHAIN (attributes) != first_attribute)
+           attributes = TREE_CHAIN (attributes);
+         if (attributes)
+           TREE_CHAIN (attributes) = NULL_TREE;
+       }
 
       DECL_CHAIN (decl) = decls;
       decls = decl;
index ad23ad741ef8c805b65a47cef92953569415272b..c4a4e3e4d7e486a789faf5d02e9e5858bd9839d2 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/83824
+       * g++.dg/cpp0x/pr83824.C: New test.
+
 2018-01-17  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/gnuattr1.c: New test to make sure we set the
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83824.C b/gcc/testsuite/g++.dg/cpp0x/pr83824.C
new file mode 100644 (file)
index 0000000..9474e1e
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/83824
+// { dg-do compile { target c++11 } }
+
+void
+foo ()
+{
+  if (alignas(1 alignas(1)))   // { dg-error "expected" }
+    ;
+}