summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-11 19:31:33 +0000
committerlmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-11 19:31:33 +0000
commitceec99b9a6dcd120ed55e7dfc246d5b7e83cf5a3 (patch)
treea7b32d64c052d1629ca208252036bb3c64a9f362
parente3625844fba13bd71af4adfd0f326875dc5d36b8 (diff)
downloadgcc-ceec99b9a6dcd120ed55e7dfc246d5b7e83cf5a3.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117641 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/other/mult-stor1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef8.C6
7 files changed, 44 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5d60bd77d13..4c7fe491a41 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 93c4053ccd6..8de90605c2b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 96ecc8691d7..befd4e86485 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2672f15afba..41fe858b5ef 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa9cd9ec134..2124585fc10 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/other/mult-stor1.C b/gcc/testsuite/g++.dg/other/mult-stor1.C
index 439c0cb084f..1eaec4f14f9 100644
--- a/gcc/testsuite/g++.dg/other/mult-stor1.C
+++ b/gcc/testsuite/g++.dg/other/mult-stor1.C
@@ -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
index 00000000000..8c46bad8cae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/typedef8.C
@@ -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" }