re PR c/67964 (Multiple attributes wrongly accepted without commas)
authorMarek Polacek <polacek@redhat.com>
Tue, 20 Oct 2015 16:53:45 +0000 (16:53 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Tue, 20 Oct 2015 16:53:45 +0000 (16:53 +0000)
PR c/67964
* c-parser.c (c_parser_attributes): Break out of the loop if the
token after an attribute isn't a comma.

* gcc.dg/pr67964.c: New test.

From-SVN: r229091

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr67964.c [new file with mode: 0644]

index a54921a145f329c9ae684e6dba3ffb5fb6de9dca..2a083c40d80b04a3ff18836e2471190b17cf3213 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-20  Marek Polacek  <polacek@redhat.com>
+
+       PR c/67964
+       * c-parser.c (c_parser_attributes): Break out of the loop if the
+       token after an attribute isn't a comma.
+
 2015-10-13  Jakub Jelinek  <jakub@redhat.com>
            Aldy Hernandez  <aldyh@redhat.com>
 
index 704ebc6bdc6e8a2c3fc677097f771288714ed078..e7b84400b5adca0fcf1c2ec4957cab449f103f04 100644 (file)
@@ -3965,7 +3965,9 @@ c_parser_attributes (c_parser *parser)
       /* ??? Follow the C++ parser rather than using the
         lex_untranslated_string kludge.  */
       parser->lex_untranslated_string = true;
+      /* Consume the `__attribute__' keyword.  */
       c_parser_consume_token (parser);
+      /* Look for the two `(' tokens.  */
       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
        {
          parser->lex_untranslated_string = false;
@@ -3993,17 +3995,24 @@ c_parser_attributes (c_parser *parser)
          attr_name = c_parser_attribute_any_word (parser);
          if (attr_name == NULL)
            break;
-         if (is_cilkplus_vector_p (attr_name))           
+         if (is_cilkplus_vector_p (attr_name))
            {
              c_token *v_token = c_parser_peek_token (parser);
              c_parser_cilk_simd_fn_vector_attrs (parser, *v_token);
+             /* If the next token isn't a comma, we're done.  */
+             if (!c_parser_next_token_is (parser, CPP_COMMA))
+               break;
              continue;
            }
          c_parser_consume_token (parser);
          if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
            {
              attr = build_tree_list (attr_name, NULL_TREE);
+             /* Add this attribute to the list.  */
              attrs = chainon (attrs, attr);
+             /* If the next token isn't a comma, we're done.  */
+             if (!c_parser_next_token_is (parser, CPP_COMMA))
+               break;
              continue;
            }
          c_parser_consume_token (parser);
@@ -4062,8 +4071,13 @@ c_parser_attributes (c_parser *parser)
                                         "expected %<)%>");
              return attrs;
            }
+         /* Add this attribute to the list.  */
          attrs = chainon (attrs, attr);
+         /* If the next token isn't a comma, we're done.  */
+         if (!c_parser_next_token_is (parser, CPP_COMMA))
+           break;
        }
+      /* Look for the two `)' tokens.  */
       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
        c_parser_consume_token (parser);
       else
index 8620128cdff8acb2afaa8779f24106a2f76b81d1..2e06853321d60bbed56b4231fad5e5aae1249b0e 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-20  Marek Polacek  <polacek@redhat.com>
+
+       PR c/67964
+       * gcc.dg/pr67964.c: New test.
+
 2015-10-20  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/67609
diff --git a/gcc/testsuite/gcc.dg/pr67964.c b/gcc/testsuite/gcc.dg/pr67964.c
new file mode 100644 (file)
index 0000000..095b50f
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR c/67964 */
+/* { dg-do compile } */
+
+extern int fn0 (void) __attribute__ ((const const)); /* { dg-error "expected" } */
+extern int fn1 (void) __attribute__ ((const, const));
+extern int fn2 (void) __attribute__ ((optimize (0) const)); /* { dg-error "expected" } */
+extern int fn3 (void) __attribute__ ((optimize (0), const));
+/* We allow starting/trailing comma.  */
+extern int fn4 (void) __attribute__ ((, const));
+extern int fn5 (void) __attribute__ ((const, ));
+extern int fn6 (void) __attribute__ ((,,,, const,,,,, ));
+extern int fn7 (void) __attribute__ ((,));
+extern int fn8 (void) __attribute__ ((__noreturn__ __noreturn__)); /* { dg-error "expected" } */
+extern int fn9 (void) __attribute__ ((__noreturn__, __noreturn__));
+extern int fn10 (void) __attribute__ ((__cold__ __pure__ __noclone__)); /* { dg-error "expected" } */
+extern int fn11 (void) __attribute__ ((__cold__, __pure__ __noclone__)); /* { dg-error "expected" } */
+int i;
+int ii;
+extern int a __attribute__ ((alias ("i") unused)); /* { dg-error "expected" } */
+extern int a2 __attribute__ ((alias ("i" "i")));
+struct A { char p[6]; } __attribute__((__packed__ packed)); /* { dg-error "expected" } */