+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.
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. */
/* 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
/* 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:
}
else if (decl_specs->storage_class != sc_none)
{
- decl_specs->multiple_storage_classes_p = true;
+ decl_specs->conflicting_specifiers_p = true;
return;
}
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
+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
struct A
{
- extern static int i; // { dg-error "multiple storage classes" }
+ extern static int i; // { dg-error "conflicting specifiers" }
};
--- /dev/null
+//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" }