re PR c++/26151 (duplicate 'duplicate' diagnostic)
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>
Mon, 13 Feb 2006 10:29:31 +0000 (10:29 +0000)
committerVolker Reichelt <reichelt@gcc.gnu.org>
Mon, 13 Feb 2006 10:29:31 +0000 (10:29 +0000)
PR c++/26151
* parser.c (cp_parser_decl_specifier_seq): Check for duplicate
decl-specifiers.  Remove extra check for duplicate 'friend'.
* decl.c (grokdeclarator): Remove check for duplicate
decl-specifiers.  Set longlong together with long_p.

From-SVN: r110911

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/parser.c

index cbab739740ca718e31bb0f06177927156f974962..fc53be07e7cd813d0413e0dd1c91caa1880969af 100644 (file)
@@ -1,3 +1,11 @@
+2006-02-13  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+       PR c++/26151
+       * parser.c (cp_parser_decl_specifier_seq): Check for duplicate
+       decl-specifiers.  Remove extra check for duplicate 'friend'.
+       * decl.c (grokdeclarator): Remove check for duplicate
+       decl-specifiers.  Set longlong together with long_p.
+
 2006-02-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/24996
index bb898b420bfba7915edba5f41d0a556e4b2fc6fc..b00ac7a9ba90e5aff1f9abb5536e4cd3f6352e14 100644 (file)
@@ -6662,7 +6662,6 @@ grokdeclarator (const cp_declarator *declarator,
      this value will be NULL_TREE, even if the entity is located at
      namespace scope.  */
   tree in_namespace = NULL_TREE;
-  cp_decl_spec ds;
   cp_storage_class storage_class;
   bool unsigned_p, signed_p, short_p, long_p, thread_p;
   bool type_was_error_mark_node = false;
@@ -6671,6 +6670,7 @@ grokdeclarator (const cp_declarator *declarator,
   unsigned_p = declspecs->specs[(int)ds_unsigned];
   short_p = declspecs->specs[(int)ds_short];
   long_p = declspecs->specs[(int)ds_long];
+  longlong = declspecs->specs[(int)ds_long] >= 2;
   thread_p = declspecs->specs[(int)ds_thread];
 
   if (decl_context == FUNCDEF)
@@ -6884,45 +6884,6 @@ grokdeclarator (const cp_declarator *declarator,
   explicit_int = declspecs->explicit_int_p;
   explicit_char = declspecs->explicit_char_p;
 
-  /* Check for repeated decl-specifiers.  */
-  for (ds = ds_first; ds != ds_last; ++ds)
-    {
-      unsigned count = declspecs->specs[(int)ds];
-      if (count < 2)
-       continue;
-      /* The "long" specifier is a special case because of
-        "long long".  */
-      if (ds == ds_long)
-       {
-         if (count > 2)
-           error ("%<long long long%> is too long for GCC");
-         else if (pedantic && !in_system_header && warn_long_long)
-           pedwarn ("ISO C++ does not support %<long long%>");
-         else
-           longlong = 1;
-       }
-      else if (declspecs->specs[(int)ds] > 1)
-       {
-         static const char *const decl_spec_names[] = {
-           "signed",
-           "unsigned",
-           "short",
-           "long",
-           "const",
-           "volatile",
-           "restrict",
-           "inline",
-           "virtual",
-           "explicit",
-           "friend",
-           "typedef",
-           "__complex",
-           "__thread"
-         };
-         error ("duplicate %qs", decl_spec_names[(int)ds]);
-       }
-    }
-
 #if 0
   /* See the code below that used this.  */
   if (typedef_decl)
index bba4d25616d39a42504591c2a16ff85b47c37f68..37df31160d22928afb11ca25669606ef91ed4e3b 100644 (file)
@@ -7330,6 +7330,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
                              int* declares_class_or_enum)
 {
   bool constructor_possible_p = !parser->in_declarator_p;
+  cp_decl_spec ds;
 
   /* Clear DECL_SPECS.  */
   clear_decl_specs (decl_specs);
@@ -7364,8 +7365,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
          /* decl-specifier:
               friend  */
        case RID_FRIEND:
-         if (decl_specs->specs[(int) ds_friend]++)
-           error ("duplicate %<friend%>");
+         ++decl_specs->specs[(int) ds_friend];
          /* Consume the token.  */
          cp_lexer_consume_token (parser->lexer);
          break;
@@ -7531,6 +7531,42 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
       flags |= CP_PARSER_FLAGS_OPTIONAL;
     }
 
+  /* Check for repeated decl-specifiers.  */
+  for (ds = ds_first; ds != ds_last; ++ds)
+    {
+      unsigned count = decl_specs->specs[(int)ds];
+      if (count < 2)
+       continue;
+      /* The "long" specifier is a special case because of "long long".  */
+      if (ds == ds_long)
+       {
+         if (count > 2)
+           error ("%<long long long%> is too long for GCC");
+         else if (pedantic && !in_system_header && warn_long_long)
+           pedwarn ("ISO C++ does not support %<long long%>");
+       }
+      else if (count > 1)
+       {
+         static const char *const decl_spec_names[] = {
+           "signed",
+           "unsigned",
+           "short",
+           "long",
+           "const",
+           "volatile",
+           "restrict",
+           "inline",
+           "virtual",
+           "explicit",
+           "friend",
+           "typedef",
+           "__complex",
+           "__thread"
+         };
+         error ("duplicate %qs", decl_spec_names[(int)ds]);
+       }
+    }
+
   /* Don't allow a friend specifier with a class definition.  */
   if (decl_specs->specs[(int) ds_friend] != 0
       && (*declares_class_or_enum & 2))