re PR c++/29024 (storage class specifier accepted for typedef (clause 7.1.1 ; 1))
authorLee Millward <lee.millward@codesourcery.com>
Wed, 11 Oct 2006 19:31:33 +0000 (19:31 +0000)
committerLee Millward <lmillward@gcc.gnu.org>
Wed, 11 Oct 2006 19:31:33 +0000 (19:31 +0000)
        PR c++/29024
        * cp-tree (struct cp_decl_specifier_seq): Rename to
        conflicting_specifiers_p
        * parser.c (cp_parser_set_storage_class): Set
        conflicting_specifiers_p for the input decl specifier
        if a typedef specifier is present. Rename uses of
        multiple_specifiers_p to conflicting_specifiers_p.
        (cp_parser_decl_specifier_seq) <RID_TYPEDEF>: If a storage
        class specifier has already been set for this declaration,
        set conflicting_specifiers_p to true on the decl_specs.
        * decl.c (grokdeclarator): Rename uses of
        multiple_specifiers_p to conflicting_specifiers_p.

        * g++.dg/parse/typedef8.C: New test.
        * g++.dg/other/mult-stor1.C: Adjust error markers.

From-SVN: r117641

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/mult-stor1.C
gcc/testsuite/g++.dg/parse/typedef8.C [new file with mode: 0644]

index 5d60bd77d13d720665ba165542226714d25eccf4..4c7fe491a41f52668e8ef6b577e9a724427c572e 100644 (file)
@@ -1,3 +1,18 @@
+2006-10-11  Lee Millward  <lee.millward@codesourcery.com>
+
+       PR c++/29024
+        * cp-tree (struct cp_decl_specifier_seq): Rename to 
+        conflicting_specifiers_p
+        * parser.c (cp_parser_set_storage_class): Set
+        conflicting_specifiers_p for the input decl specifier 
+        if a typedef specifier is present. Rename uses of
+        multiple_specifiers_p to conflicting_specifiers_p.
+        (cp_parser_decl_specifier_seq) <RID_TYPEDEF>: If a storage 
+        class specifier has already been set for this declaration, 
+        set conflicting_specifiers_p to true on the decl_specs.
+        * decl.c (grokdeclarator): Rename uses of
+        multiple_specifiers_p to conflicting_specifiers_p.
+
 2006-10-10  Brooks Moses  <bmoses@stanford.edu>
 
        * Make-lang.in: Added "c++.pdf" target support.
index 93c4053ccd6e9cc2da7e6996234c2daf02fd2277..8de90605c2bc37748e7fd7b882bd7ac8ace07475 100644 (file)
@@ -3655,8 +3655,9 @@ typedef struct cp_decl_specifier_seq {
      decl-specifier-seq.  */
   BOOL_BITFIELD multiple_types_p : 1;
   /* True iff multiple storage classes were (erroneously) specified
-     for this decl-specifier-seq.  */
-  BOOL_BITFIELD multiple_storage_classes_p : 1;
+     for this decl-specifier-seq or a combination of a storage class
+     with a typedef specifier.  */
+  BOOL_BITFIELD conflicting_specifiers_p : 1;
   /* True iff at least one decl-specifier was found.  */
   BOOL_BITFIELD any_specifiers_p : 1;
   /* True iff "int" was explicitly provided.  */
index 96ecc8691d7a84cb803d2a8bcda59e274e9dd73c..befd4e86485eb86f8ead96311fc08764e29f5ef4 100644 (file)
@@ -7402,9 +7402,9 @@ grokdeclarator (const cp_declarator *declarator,
 
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */
-  if (declspecs->multiple_storage_classes_p)
+  if (declspecs->conflicting_specifiers_p)
     {
-      error ("multiple storage classes in declaration of %qs", name);
+      error ("conflicting specifiers in declaration of %qs", name);
       storage_class = sc_none;
     }
   else if (thread_p
index 2672f15afba7609839506e26d522377de22d7532..41fe858b5efbab99b5edad4a28979621097cf246 100644 (file)
@@ -7493,6 +7493,9 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
          /* The "typedef" keyword can only occur in a declaration; we
             may as well commit at this point.  */
          cp_parser_commit_to_tentative_parse (parser);
+
+          if (decl_specs->storage_class != sc_none)
+            decl_specs->conflicting_specifiers_p = true;
          break;
 
          /* storage-class-specifier:
@@ -16193,7 +16196,7 @@ cp_parser_set_storage_class (cp_parser *parser,
     }
   else if (decl_specs->storage_class != sc_none)
     {
-      decl_specs->multiple_storage_classes_p = true;
+      decl_specs->conflicting_specifiers_p = true;
       return;
     }
 
@@ -16225,6 +16228,13 @@ cp_parser_set_storage_class (cp_parser *parser,
       gcc_unreachable ();
     }
   decl_specs->storage_class = storage_class;
+
+  /* A storage class specifier cannot be applied alongside a typedef 
+     specifier. If there is a typedef specifier present then set 
+     conflicting_specifiers_p which will trigger an error later
+     on in grokdeclarator. */
+  if (decl_specs->specs[(int)ds_typedef])
+    decl_specs->conflicting_specifiers_p = true;
 }
 
 /* Update the DECL_SPECS to reflect the TYPE_SPEC.  If USER_DEFINED_P
index aa9cd9ec1345dbd96fc3ee33e98640c1773edb53..2124585fc10c1ee8f7c850942ea52c5362733973 100644 (file)
@@ -1,3 +1,9 @@
+2006-10-11  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/29024
+        * g++.dg/parse/typedef8.C: New test.
+        * g++.dg/other/mult-stor1.C: Adjust error markers.
+       
 2006-10-11  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/28230
index 439c0cb084f5599d02587b64228cd8b029fe6dee..1eaec4f14f9b37d94656e7990cda3250832d1dcb 100644 (file)
@@ -4,5 +4,5 @@
 
 struct A
 {
-  extern static int i;  // { dg-error "multiple storage classes" }
+  extern static int i;  // { dg-error "conflicting specifiers" }
 };
diff --git a/gcc/testsuite/g++.dg/parse/typedef8.C b/gcc/testsuite/g++.dg/parse/typedef8.C
new file mode 100644 (file)
index 0000000..8c46bad
--- /dev/null
@@ -0,0 +1,6 @@
+//PR c++ 29024
+
+typedef static int a;   // { dg-error "conflicting" }
+typedef register int b; // { dg-error "conflicting" }
+typedef extern int c;   // { dg-error "conflicting" }
+static typedef int a;   // { dg-error "conflicting" }