This source file is rejected: struct a { struct { int x; } volatile a; }; /* OK */ struct b { volatile struct { int x; } ; }; /* OK */ struct c { struct { int x; } volatile; }; /* ERROR */ theseus$ gcc -Wall -c t.c t.c:10: unnamed fields of type other than struct or union are not allowed This code is made up to demonstrate a problem found while reading the source: grokfield is called for a field declaration without an identifier and tries to check that the field type is a structure or union. However, grokfield assumes that the type specifier is the first element in the list passed as declspecs which is not necessarily true. Given the other two examples (struct a and struct b) which are accepted this code should probably be legal. Even if it is illegal the error message is wrong. Release: gcc-3.2 Environment: theseus$ uname -a SunOS theseus 5.9 Generic_112233-02 sun4u sparc SUNW,Ultra-4 theseus$ gcc -v Reading specs from /usr/local/bin/../lib/gcc-lib/sparc-sun-solaris2.9/3.2/specs Configured with: /export/local/manager/playground/ULMgcc32/src/gcc-3.2/configure --with-ld=/usr/local/bin/ld --with-gnu-ld --with-as=/usr/local/bin/as --with-gnu-as --prefix=/usr/local/ Thread model: posix gcc version 3.2 How-To-Repeat: See description above.
Fix: A workaround is to move the volatile keyword before the struct.
State-Changed-From-To: open->analyzed State-Changed-Why: Confirmed.
From: Richard Henderson <rth@redhat.com> To: ehrhardt@mathematik.uni-ulm.de Cc: gcc-gnats@gcc.gnu.org Subject: Re: c/8420: volatile after the type specifier for an unnamed structure is rejected Date: Wed, 11 Dec 2002 15:40:19 -0800 On Fri, Nov 01, 2002 at 10:14:09AM -0000, ehrhardt@mathematik.uni-ulm.de wrote: > struct c { > struct { int x; } volatile; > }; /* ERROR */ > > theseus$ gcc -Wall -c t.c > t.c:10: unnamed fields of type other than struct or union are not allowed [...] > Given the other two examples (struct a and struct b) which are accepted > this code should probably be legal. I don't agree. I think this is very confusing syntax. > Even if it is illegal the error message is wrong. Granted. r~
From: "Christian Ehrhardt" <ehrhardt@mathematik.uni-ulm.de> To: Richard Henderson <rth@redhat.com> Cc: gcc-gnats@gcc.gnu.org Subject: Re: c/8420: volatile after the type specifier for an unnamed structure is rejected Date: Thu, 12 Dec 2002 01:34:25 +0100 On Wed, Dec 11, 2002 at 03:40:19PM -0800, Richard Henderson wrote: > On Fri, Nov 01, 2002 at 10:14:09AM -0000, ehrhardt@mathematik.uni-ulm.de wrote: > > struct c { > > struct { int x; } volatile; > > }; /* ERROR */ > > > > theseus$ gcc -Wall -c t.c > > t.c:10: unnamed fields of type other than struct or union are not allowed > [...] > > Given the other two examples (struct a and struct b) which are accepted > > this code should probably be legal. > > I don't agree. I think this is very confusing syntax. I agree that it is confusing, but normally the order in which type specifiers and type qualifiers appear is irrelevant. This is shown by the fact that struct { struct { int a; } volatile name; } X; is accepted and legal. If we continue to allow this we should also allow it for anon structs. Having said that I don't particularly care about this, as already said in the orignal report this is to point out what looks like an oversight in c-decl.c: The declspecs passed to grokfield may contain qualifiers and it is not safe to assume that the type specifier is the last thing in a declspec and hence the first thing in the declspec list as returned from the parser. > > Even if it is illegal the error message is wrong. > > Granted. 3.3. meanwhile gives a somewhat better message. The proper solution is IMHO to move the whole check for unnamed types from grokfield to grokdeclarator and do the check when we know which element on the declspec list is the type specifier. regards Christian -- THAT'S ALL FOLKS!
On the mainline (20030821) we get a warning which looks wrong: pr8420.c:12: warning: declaration does not declare anything
In C99 mode I also get an warning about the 2nd struct and the 3rd: Perf-Evals-Computer:~/src/gccPRs peg$ ~/fsf-clean-nocheck/bin/gcc pr8420.c -std=c99 pr8420.c:6: warning: declaration does not declare anything pr8420.c:10: warning: declaration does not declare anything
For C99 mode it is right to rejct it as there are no such things as anonymous structs.
Subject: Bug 8420 CVSROOT: /cvs/gcc Module name: gcc Changes by: jsm28@gcc.gnu.org 2004-09-09 01:25:49 Modified files: gcc : ChangeLog c-decl.c c-parse.in c-tree.h gcc/testsuite : ChangeLog gcc/testsuite/gcc.dg/tls: diag-2.c Added files: gcc/testsuite/gcc.dg: anon-struct-4.c declspec-1.c declspec-2.c declspec-3.c declspec-4.c declspec-5.c declspec-6.c long-long-typespec-1.c Log message: 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 Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.5316&r2=2.5317 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-decl.c.diff?cvsroot=gcc&r1=1.576&r2=1.577 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-parse.in.diff?cvsroot=gcc&r1=1.237&r2=1.238 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-tree.h.diff?cvsroot=gcc&r1=1.178&r2=1.179 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4251&r2=1.4252 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/anon-struct-4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-2.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-3.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/declspec-6.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/long-long-typespec-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tls/diag-2.c.diff?cvsroot=gcc&r1=1.1&r2=1.2
Fixed.