From: Lee Millward Date: Wed, 11 Oct 2006 19:31:33 +0000 (+0000) Subject: re PR c++/29024 (storage class specifier accepted for typedef (clause 7.1.1 ; 1)) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2610654299771d3fe46c1c55bb797e78810a72cd;p=gcc.git re PR c++/29024 (storage class specifier accepted for typedef (clause 7.1.1 ; 1)) 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) : 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 --- 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 + + 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) : 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 * 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 + + PR c++/29024 + * g++.dg/parse/typedef8.C: New test. + * g++.dg/other/mult-stor1.C: Adjust error markers. + 2006-10-11 Richard Guenther 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" }