diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/gcc.dg/c99-tag-3.c | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/gcc.dg/c99-tag-3.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/c99-tag-3.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/c99-tag-3.c b/gcc/testsuite/gcc.dg/c99-tag-3.c new file mode 100644 index 000000000..a492037b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-tag-3.c @@ -0,0 +1,59 @@ +/* Test for handling of tags. "const struct foo;" and similar does + not redeclare an existing tag. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +/* Plain "struct s;" always declares a tag: the same as one declared + in that scope, or shadowing one from an outer scope. */ +struct s0; +struct s0 { int a; }; +struct s0; +void f (void) { struct s0; } + +/* A declaration with a qualifier or storage class specifier declares + the tag if no other declaration of it is visible. */ +const union u0; /* { dg-warning "13:useless type qualifier in empty declaration" } */ +union u0 { long b; }; + +extern struct s1; /* { dg-warning "15:useless storage class specifier in empty declaration" } */ + +/* But if a declaration of the tag is visible, whether at the same + scope or an outer scope, the declaration specifies the same type as + the previous declaration and does not redeclare the tag (C99 + 6.7.2.3#8). Thus, as it does not declare a declarator, a tag or + the members of an enumeration, it is a constraint violation. */ + +struct s2 { char x; }; +const struct s2; /* { dg-error "14:empty declaration with type qualifier does not redeclare tag" } */ + +union u1; +extern union u1; /* { dg-error "14:empty declaration with storage class specifier does not redeclare tag" } */ + +union u2 { long b; }; +void g(void) { const union u2; } /* { dg-error "28:empty declaration with type qualifier does not redeclare tag" } */ + +/* And it does not redeclare the tag either if the outer tag is the + wrong kind of tag. This also yields an error for the reference to + the wrong kind of tag in addition to the pedwarn for the empty + declaration. */ + +union u3 { float v; }; +void h(void) { const struct u3; } /* { dg-error "29:'u3' defined as wrong kind of tag" } */ +/* { dg-error "29:empty declaration with type qualifier does not redeclare tag" "wrong tag empty" { target *-*-* } 42 } */ + +/* However, such useless specifiers are OK if the contents of the tag + are being defined, or shadowed in an inner scope with the contents + included in the shadowing. */ + +struct s3; +const struct s3 { int a; }; /* { dg-warning "14:useless type qualifier in empty declaration" } */ + +union u4; +extern union u4 { int z; }; /* { dg-warning "14:useless storage class specifier in empty declaration" } */ + +enum e0 { E0 }; +void i(void) { const enum e0 { E1 }; } /* { dg-warning "32:useless type qualifier in empty declaration" } */ + +union u5 { int p; }; +void j(void) { extern struct u5 { int q; }; } /* { dg-warning "30:useless storage class specifier in empty declaration" } */ |