Commit deb176fa by Joseph Myers Committed by Joseph Myers

re PR c/8420 (volatile after the type specifier for an unnamed structure is rejected)

	PR c/8420
	* c-tree.h (struct c_declspecs): New.
	(struct c_declarator, struct c_type_name, struct c_parm): Update
	element types.
	(build_array_declarator, grokfield, shadow_tag, shadow_tag_warned,
	start_function, start_decl, build_c_parm,
	make_pointer_declarator): Update prototypes.
	(build_null_declspecs, declspecs_add_qual, declspecs_add_type,
	declspecs_add_scspec, declspecs_add_attrs): New.
	(split_specs_attrs): Remove.
	* c-parse.in (%union): Add dsptype.
	(declspecs_nosc_nots_nosa_noea, declspecs_nosc_nots_nosa_ea,
	declspecs_nosc_nots_sa_noea, declspecs_nosc_nots_sa_ea,
	declspecs_nosc_ts_nosa_noea, declspecs_nosc_ts_nosa_ea,
	declspecs_nosc_ts_sa_noea, declspecs_nosc_ts_sa_ea,
	declspecs_sc_nots_nosa_noea, declspecs_sc_nots_nosa_ea,
	declspecs_sc_nots_sa_noea, declspecs_sc_nots_sa_ea,
	declspecs_sc_ts_nosa_noea, declspecs_sc_ts_nosa_ea,
	declspecs_sc_ts_sa_noea, declspecs_sc_ts_sa_ea, declspecs_ts,
	declspecs_nots, declspecs_ts_nosa, declspecs_nots_nosa,
	declspecs_nosc_ts, declspecs_nosc_nots, declspecs_nosc, declspecs,
	maybe_type_quals_attrs): Change to dsptype.
	(struct c_declspec_stack): New.
	(current_declspecs, declspec_stack): Change type.
	(PUSH_DECLSPEC_STACK, POP_DECLSPEC_STACK): Update to new
	structures.
	(extdefs): Likewise.
	(setspecs): Likewise.
	(fndef): Use current_declspecs for empty declspecs list.
	(declspecs_nosc_nots_nosa_noea, declspecs_nosc_nots_nosa_ea,
	declspecs_nosc_nots_sa_noea, declspecs_nosc_nots_sa_ea,
	declspecs_nosc_ts_nosa_noea, declspecs_nosc_ts_nosa_ea,
	declspecs_nosc_ts_sa_noea, declspecs_nosc_ts_sa_ea,
	declspecs_sc_nots_nosa_noea, declspecs_sc_nots_nosa_ea,
	declspecs_sc_nots_sa_noea, declspecs_sc_nots_sa_ea,
	declspecs_sc_ts_nosa_noea, declspecs_sc_ts_nosa_ea,
	declspecs_sc_ts_sa_noea, declspecs_sc_ts_sa_ea): Update to new
	structures and helper functions.  Update comments.
	(typespec_nonattr): Correct comment.
	(maybe_type_quals_attrs, typename): Update to new structures.
	* c-decl.c (grokdeclarator, build_array_declarator, grokfield,
	shadow_tag, shadow_tag_warned, start_function, start_decl,
	build_c_parm, make_pointer_declarator,
	set_array_declarator_inner, groktypename): Update to new
	structures.
	(build_null_declspecs, declspecs_add_qual, declspecs_add_type,
	declspecs_add_scspec, declspecs_add_attrs): New.
	(split_specs_attrs): Remove.
	(shadow_tag_warned): Make warning for useless type names a
	pedwarn.  Give hard error for long, short, signed, unsigned or
	_Complex used with struct, union or enum in empty declaration.
	Make found_tag a bool.
	(grokdeclarator): Remove checks now done at parse time.

testsuite:
	* gcc.dg/anon-struct-4.c, gcc.dg/declspec-1.c,
	gcc.dg/declspec-2.c, gcc.dg/declspec-3.c, gcc.dg/declspec-4.c,
	gcc.dg/declspec-5.c, gcc.dg/declspec-6.c,
	gcc.dg/long-long-typespec-1.c: New tests.
	* gcc.dg/tls/diag-2.c: Update expected diagnostics

From-SVN: r87218
parent f8893e47
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/8420
* c-tree.h (struct c_declspecs): New.
(struct c_declarator, struct c_type_name, struct c_parm): Update
element types.
(build_array_declarator, grokfield, shadow_tag, shadow_tag_warned,
start_function, start_decl, build_c_parm,
make_pointer_declarator): Update prototypes.
(build_null_declspecs, declspecs_add_qual, declspecs_add_type,
declspecs_add_scspec, declspecs_add_attrs): New.
(split_specs_attrs): Remove.
* c-parse.in (%union): Add dsptype.
(declspecs_nosc_nots_nosa_noea, declspecs_nosc_nots_nosa_ea,
declspecs_nosc_nots_sa_noea, declspecs_nosc_nots_sa_ea,
declspecs_nosc_ts_nosa_noea, declspecs_nosc_ts_nosa_ea,
declspecs_nosc_ts_sa_noea, declspecs_nosc_ts_sa_ea,
declspecs_sc_nots_nosa_noea, declspecs_sc_nots_nosa_ea,
declspecs_sc_nots_sa_noea, declspecs_sc_nots_sa_ea,
declspecs_sc_ts_nosa_noea, declspecs_sc_ts_nosa_ea,
declspecs_sc_ts_sa_noea, declspecs_sc_ts_sa_ea, declspecs_ts,
declspecs_nots, declspecs_ts_nosa, declspecs_nots_nosa,
declspecs_nosc_ts, declspecs_nosc_nots, declspecs_nosc, declspecs,
maybe_type_quals_attrs): Change to dsptype.
(struct c_declspec_stack): New.
(current_declspecs, declspec_stack): Change type.
(PUSH_DECLSPEC_STACK, POP_DECLSPEC_STACK): Update to new
structures.
(extdefs): Likewise.
(setspecs): Likewise.
(fndef): Use current_declspecs for empty declspecs list.
(declspecs_nosc_nots_nosa_noea, declspecs_nosc_nots_nosa_ea,
declspecs_nosc_nots_sa_noea, declspecs_nosc_nots_sa_ea,
declspecs_nosc_ts_nosa_noea, declspecs_nosc_ts_nosa_ea,
declspecs_nosc_ts_sa_noea, declspecs_nosc_ts_sa_ea,
declspecs_sc_nots_nosa_noea, declspecs_sc_nots_nosa_ea,
declspecs_sc_nots_sa_noea, declspecs_sc_nots_sa_ea,
declspecs_sc_ts_nosa_noea, declspecs_sc_ts_nosa_ea,
declspecs_sc_ts_sa_noea, declspecs_sc_ts_sa_ea): Update to new
structures and helper functions. Update comments.
(typespec_nonattr): Correct comment.
(maybe_type_quals_attrs, typename): Update to new structures.
* c-decl.c (grokdeclarator, build_array_declarator, grokfield,
shadow_tag, shadow_tag_warned, start_function, start_decl,
build_c_parm, make_pointer_declarator,
set_array_declarator_inner, groktypename): Update to new
structures.
(build_null_declspecs, declspecs_add_qual, declspecs_add_type,
declspecs_add_scspec, declspecs_add_attrs): New.
(split_specs_attrs): Remove.
(shadow_tag_warned): Make warning for useless type names a
pedwarn. Give hard error for long, short, signed, unsigned or
_Complex used with struct, union or enum in empty declaration.
Make found_tag a bool.
(grokdeclarator): Remove checks now done at parse time.
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
* c-tree.h (enum c_declarator_kind, struct c_arg_info, struct
c_declarator, struct c_type_name, struct c_parm): New.
(build_array_declarator, set_array_declarator_inner,
......
......@@ -131,6 +131,38 @@ struct c_expr
enum tree_code original_code;
};
/* A sequence of declaration specifiers in C. */
struct c_declspecs {
/* The type specified, not reflecting modifiers such as "short" and
"unsigned", or NULL_TREE if none. */
tree type;
/* If the type was specified with a typedef, that typedef decl. */
tree typedef_decl;
/* The attributes from a typedef decl. */
tree decl_attr;
/* When parsing, the attributes. Outside the parser, this will be
NULL; attributes (possibly from multiple lists) will be passed
separately. */
tree attrs;
/* The modifier bits present. */
int specbits;
/* Whether something other than a storage class specifier or
attribute has been seen. This is used to warn for the
obsolescent usage of storage class specifiers other than at the
start of the list. (Doing this properly would require function
specifiers to be handled separately from storage class
specifiers.) */
BOOL_BITFIELD non_sc_seen_p : 1;
/* Whether the specifiers include a deprecated typedef. */
BOOL_BITFIELD deprecated_p : 1;
/* Whether "int" was explicitly specified. */
BOOL_BITFIELD explicit_int_p : 1;
/* Whether "char" was explicitly specified. */
BOOL_BITFIELD explicit_char_p : 1;
/* Whether "long" was specified more than once. */
BOOL_BITFIELD long_long_p : 1;
};
/* The various kinds of declarators in C. */
enum c_declarator_kind {
/* An identifier. */
......@@ -175,14 +207,14 @@ struct c_declarator {
/* The array dimension, or NULL for [] and [*]. */
tree dimen;
/* The qualifiers (and attributes, currently ignored) inside []. */
tree quals;
struct c_declspecs *quals;
/* Whether [static] was used. */
BOOL_BITFIELD static_p : 1;
/* Whether [*] was used. */
BOOL_BITFIELD vla_unspec_p : 1;
} array;
/* For pointers, the qualifiers on the pointer type. */
tree pointer_quals;
struct c_declspecs *pointer_quals;
/* For attributes. */
tree attrs;
} u;
......@@ -191,7 +223,7 @@ struct c_declarator {
/* A type name. */
struct c_type_name {
/* The declaration specifiers. */
tree specs;
struct c_declspecs *specs;
/* The declarator. */
struct c_declarator *declarator;
};
......@@ -199,7 +231,7 @@ struct c_type_name {
/* A parameter. */
struct c_parm {
/* The declaration specifiers, minus any prefix attributes. */
tree specs;
struct c_declspecs *specs;
/* The attributes. */
tree attrs;
/* The declarator. */
......@@ -246,7 +278,8 @@ extern void c_expand_body (tree);
extern void c_init_decl_processing (void);
extern void c_dup_lang_specific_decl (tree);
extern void c_print_identifier (FILE *, tree, int);
extern struct c_declarator *build_array_declarator (tree, tree, bool, bool);
extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
bool, bool);
extern tree build_enumerator (tree, tree);
extern void check_for_loop_decls (void);
extern void mark_forward_parm_decls (void);
......@@ -260,8 +293,7 @@ extern tree finish_enum (tree, tree, tree);
extern void finish_function (void);
extern tree finish_struct (tree, tree, tree);
extern struct c_arg_info *get_parm_info (bool);
extern tree grokfield (struct c_declarator *, tree, tree);
extern void split_specs_attrs (tree, tree *, tree *);
extern tree grokfield (struct c_declarator *, struct c_declspecs *, tree);
extern tree groktypename (struct c_type_name *);
extern tree grokparm (const struct c_parm *);
extern tree implicitly_declare (tree);
......@@ -277,24 +309,31 @@ extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
bool);
extern tree builtin_function (const char *, tree, int, enum built_in_class,
const char *, tree);
extern void shadow_tag (tree);
extern void shadow_tag_warned (tree, int);
extern void shadow_tag (const struct c_declspecs *);
extern void shadow_tag_warned (const struct c_declspecs *, int);
extern tree start_enum (tree);
extern int start_function (tree, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, tree, bool, tree);
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
tree);
extern tree start_struct (enum tree_code, tree);
extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *);
extern tree xref_tag (enum tree_code, tree);
extern int c_expand_decl (tree);
extern struct c_parm *build_c_parm (tree, tree, struct c_declarator *);
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
struct c_declarator *);
extern struct c_declarator *build_attrs_declarator (tree,
struct c_declarator *);
extern struct c_declarator *build_function_declarator (struct c_arg_info *,
struct c_declarator *);
extern struct c_declarator *build_id_declarator (tree);
extern struct c_declarator *make_pointer_declarator (tree,
extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
struct c_declarator *);
extern struct c_declspecs *build_null_declspecs (void);
extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_type (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
/* in c-objc-common.c */
extern int c_disregard_inline_limits (tree);
......
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/8420
* gcc.dg/anon-struct-4.c, gcc.dg/declspec-1.c,
gcc.dg/declspec-2.c, gcc.dg/declspec-3.c, gcc.dg/declspec-4.c,
gcc.dg/declspec-5.c, gcc.dg/declspec-6.c,
gcc.dg/long-long-typespec-1.c: New tests.
* gcc.dg/tls/diag-2.c: Update expected diagnostics
2004-09-09 Joseph S. Myers <jsm@polyomino.org.uk>
* gcc.dg/c90-static-1.c, gcc.dg/c99-static-1.c,
gcc.dg/gnu99-static-1.c: New tests.
......
/* Test anonymous structures with type qualifiers. Bug 8420. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
struct s {
struct { int a; };
const struct { int b; };
struct { int c; } volatile;
};
/* Test declaration specifiers. Test cases that used to be handled in
a loop in grokdeclarator. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
typedef int t;
/* These should all be diagnosed, but only once, not for every
identifier declared. */
struct s0 int x0, /* { dg-error "two or more data types" } */
x1;
char union u0 x2, /* { dg-error "two or more data types" } */
x3;
enum e0 struct s1 x4, /* { dg-error "two or more data types" } */
x5;
short short x6, /* { dg-error "duplicate" } */
x7;
t int x8, /* { dg-error "two or more data types" } */
x9;
long long long x10, /* { dg-error "long long long" } */
x11;
/* Test declaration specifiers. Test cases that used to be handled in
a loop in grokdeclarator. Pedantic cases. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-std=gnu89 -pedantic" } */
/* These should all be diagnosed, but only once, not for every
identifier declared. */
const const int x0, /* { dg-warning "duplicate" } */
x1;
long long x2, /* { dg-warning "long long" } */
x3;
/* Test declaration specifiers. Test diagnosis of storage class
specifiers not at start. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-W" } */
static int x0;
int static x1; /* { dg-warning "not at beginning" } */
extern int x2;
int extern x3; /* { dg-warning "not at beginning" } */
typedef int x4;
int typedef x5; /* { dg-warning "not at beginning" } */
void g (int);
void
f (void)
{
auto int x6 = 0;
int auto x7 = 0; /* { dg-warning "not at beginning" } */
register int x8 = 0;
int register x9 = 0; /* { dg-warning "not at beginning" } */
g (x6 + x7 + x8 + x9);
}
const static int x10; /* { dg-warning "not at beginning" } */
/* Attributes are OK before storage class specifiers, since some
attributes are like such specifiers themselves. */
__attribute__((format(printf, 1, 2))) static void h (const char *, ...);
__attribute__((format(printf, 1, 2))) void static i (const char *, ...); /* { dg-warning "not at beginning" } */
/* Test declaration specifiers. Test empty declarations. Test with
no special options. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "" } */
/* If a declaration does not declare a declarator, it must declare a
tag or the members of an enumeration, and must only contain one
type specifier. */
typedef int T;
struct s0;
union u0;
enum e0; /* A GNU extension. */
enum { E0 };
enum e1 { E1 };
/* Not declaring anything (pedwarns). */
struct { int a; }; /* { dg-warning "warning: unnamed struct/union that defines no instances" } */
int; /* { dg-warning "warning: useless type name in empty declaration" } */
long; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-warning "warning: empty declaration" "long" { target *-*-* } 22 } */
T; /* { dg-warning "warning: useless type name in empty declaration" } */
static const; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-warning "warning: empty declaration" "long" { target *-*-* } 25 } */
union { long b; }; /* { dg-warning "warning: unnamed struct/union that defines no instances" } */
/* Multiple type names (errors). */
struct s1 int; /* { dg-error "error: two or more data types in declaration specifiers" } */
char union u1; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "char union" { target *-*-* } 31 } */
double enum { E2 }; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "double enum" { target *-*-* } 33 } */
T struct s2; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "T struct" { target *-*-* } 35 } */
long union u2; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
struct s3 short; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
union u3 signed; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
unsigned struct s4; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
_Complex enum { E3 }; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
/* Test declaration specifiers. Test empty declarations. Test with
-pedantic. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-pedantic" } */
/* If a declaration does not declare a declarator, it must declare a
tag or the members of an enumeration, and must only contain one
type specifier. */
typedef int T;
struct s0;
union u0;
enum e0; /* { dg-warning "warning: ISO C forbids forward references" } */
enum { E0 };
enum e1 { E1 };
/* Not declaring anything (pedwarns). */
struct { int a; }; /* { dg-warning "warning: unnamed struct/union that defines no instances" } */
int; /* { dg-warning "warning: useless type name in empty declaration" } */
long; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-warning "warning: empty declaration" "long" { target *-*-* } 22 } */
T; /* { dg-warning "warning: useless type name in empty declaration" } */
static const; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-warning "warning: empty declaration" "long" { target *-*-* } 25 } */
union { long b; }; /* { dg-warning "warning: unnamed struct/union that defines no instances" } */
/* Multiple type names (errors). */
struct s1 int; /* { dg-error "error: two or more data types in declaration specifiers" } */
char union u1; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "char union" { target *-*-* } 31 } */
double enum { E2 }; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "double enum" { target *-*-* } 33 } */
T struct s2; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-warning "warning: useless type name in empty declaration" "T struct" { target *-*-* } 35 } */
long union u2; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
struct s3 short; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
union u3 signed; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
unsigned struct s4; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
_Complex enum { E3 }; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
/* Test declaration specifiers. Test empty declarations. Test with
-pedantic-errors. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-pedantic-errors" } */
/* If a declaration does not declare a declarator, it must declare a
tag or the members of an enumeration, and must only contain one
type specifier. */
typedef int T;
struct s0;
union u0;
enum e0; /* { dg-error "error: ISO C forbids forward references" } */
enum { E0 };
enum e1 { E1 };
/* Not declaring anything (pedwarns). */
struct { int a; }; /* { dg-error "error: unnamed struct/union that defines no instances" } */
int; /* { dg-error "error: useless type name in empty declaration" } */
long; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-error "error: empty declaration" "long" { target *-*-* } 22 } */
T; /* { dg-error "error: useless type name in empty declaration" } */
static const; /* { dg-warning "warning: useless keyword or type name in empty declaration" } */
/* { dg-error "error: empty declaration" "long" { target *-*-* } 25 } */
union { long b; }; /* { dg-error "error: unnamed struct/union that defines no instances" } */
/* Multiple type names (errors). */
struct s1 int; /* { dg-error "error: two or more data types in declaration specifiers" } */
char union u1; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-error "error: useless type name in empty declaration" "char union" { target *-*-* } 31 } */
double enum { E2 }; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-error "error: useless type name in empty declaration" "double enum" { target *-*-* } 33 } */
T struct s2; /* { dg-error "error: two or more data types in declaration specifiers" } */
/* { dg-error "error: useless type name in empty declaration" "T struct" { target *-*-* } 35 } */
long union u2; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
struct s3 short; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
union u3 signed; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
unsigned struct s4; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
_Complex enum { E3 }; /* { dg-error "error: long, short, signed, unsigned or complex used invalidly in empty declaration" } */
/* Invalid __thread specifiers. */
__thread extern int g1; /* { dg-error "`__thread' before `extern'" } */
__thread static int g2; /* { dg-error "`__thread' before `static'" } */
__thread __thread int g3; /* { dg-error "duplicate `__thread'" } */
__thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */
__thread static int g2; /* { dg-error "'__thread' before 'static'" } */
__thread __thread int g3; /* { dg-error "duplicate '__thread'" } */
typedef __thread int g4; /* { dg-error "multiple storage classes" } */
void foo()
{
__thread int l1; /* { dg-error "implicitly auto and declared `__thread'" } */
auto __thread int l2; /* { dg-error "multiple storage classes" } */
__thread extern int l3; /* { dg-error "`__thread' before `extern'" } */
__thread extern int l3; /* { dg-error "'__thread' before 'extern'" } */
register __thread int l4; /* { dg-error "multiple storage classes" } */
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment