diff options
author | lmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-11 19:31:33 +0000 |
---|---|---|
committer | lmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-11 19:31:33 +0000 |
commit | ceec99b9a6dcd120ed55e7dfc246d5b7e83cf5a3 (patch) | |
tree | a7b32d64c052d1629ca208252036bb3c64a9f362 | |
parent | e3625844fba13bd71af4adfd0f326875dc5d36b8 (diff) | |
download | gcc-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/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/mult-stor1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/typedef8.C | 6 |
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" } |