Bug 8420 - volatile after the type specifier for an unnamed structure is rejected
Summary: volatile after the type specifier for an unnamed structure is rejected
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2002-11-01 02:16 UTC by Christian Ehrhardt
Modified: 2004-09-09 01:30 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-06-11 00:54:04


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Ehrhardt 2002-11-01 02:16:01 UTC
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.
Comment 1 Christian Ehrhardt 2002-11-01 02:16:01 UTC
Fix:
A workaround is to move the volatile keyword before the struct.
Comment 2 Wolfgang Bangerth 2002-12-02 13:09:35 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.
Comment 3 Richard Henderson 2002-12-11 15:40:19 UTC
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~

Comment 4 Christian Ehrhardt 2002-12-12 01:34:25 UTC
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!
Comment 5 Andrew Pinski 2003-08-22 02:36:40 UTC
On the mainline (20030821) we get a warning which looks wrong:
pr8420.c:12: warning: declaration does not declare anything
Comment 6 Andrew Pinski 2003-12-02 18:31:31 UTC
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
Comment 7 Andrew Pinski 2004-06-11 00:54:03 UTC
For C99 mode it is right to rejct it as there are no such things as anonymous structs.
Comment 8 GCC Commits 2004-09-09 01:25:56 UTC
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

Comment 9 Andrew Pinski 2004-09-09 01:30:23 UTC
Fixed.