Bug 15049 - [4.0 Regression] [DR 278/132/216/338/389/319] global variables with anonymous types are legal
Summary: [4.0 Regression] [DR 278/132/216/338/389/319] global variables with anonymous...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: Geoff Keating
URL:
Keywords: rejects-valid
: 17511 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-04-21 17:38 UTC by Matt Austern
Modified: 2004-09-21 18:45 UTC (History)
4 users (show)

See Also:
Host: all
Target: all
Build: all
Known to work:
Known to fail:
Last reconfirmed: 2004-04-21 17:41:10


Attachments
smime.p7s (1.63 KB, application/pkcs7-signature)
2004-07-22 22:09 UTC, Geoff Keating
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matt Austern 2004-04-21 17:38:12 UTC
The compiler recently changed to forbid the following construct, where 'x' is a global variable:
  enum { a = 77 } x;
(Or more specifically, the compiler now issues a pedwarn for this construct.  But since pedwarns are 
errors by default, it's fair to say that the compiler now forbids it.)

The comments in the code justify this by pointing to clause 3.5, paragraph 8: "A name with no linkage 
(notably, the name of a class or enumeration declared in a local scope) shall not be used to declare an 
entity with linkage".  

At the very least, this comment is wrong and needs to be clarified.  Yes, a global variable has linkage.  
But we are not declaring 'x' with "a name with no linkage".  x's type has no name, so it can't very well 
have "a name with no linkage".

I've gone through the C++ standards committee's Core Working Group issues list looking for 
clarification.  I've found a number of issues dealing with this.  The most directly relevant are:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#132 (in NAD status)
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#389 (in review status)

Issue 132 was a request that the standard be changed to forbid declaring global variables with 
anonymous types.  The committee refused to do that, and the rationale was specifically that the 
standard currently allows it and that using anonymous enums to declare variable is a common C idiom 
that the committee did not want to break.

Issue 389 is a wholesale clarification of linkage rules as they apply to anonymous types.  It is in "review" 
status, meaning that the core working group is leaning toward this solution and is looking at proposed 
precise wording.  If the wording in issue 389 is accepted, then "enum {a} x" will be forbidden.

So the current status, I think, is pretty clear: in the current C++ standard (C++03), this construct is 
legal.  It will probably be made illegal in a future version of the standard.  ("C++0x")

This means that the compiler should not reject this construct.  This is a rejects-legal.  (And I note that 
this breaks some important programs, like one of the SPEC2004 programs and the Mac version of QT.)

We should probably issue a warning for this construct, since it's likely to be made illegal someday, but 
we shouldn't issue an error.
Comment 1 Andrew Pinski 2004-04-21 17:41:10 UTC
Confirmed, assigning it to who broke it.
Comment 2 Andrew Pinski 2004-04-30 01:38:35 UTC
There is one more issue related DR 278, 338 and 216 and more.

Suspending untill all of these are resolved.
Comment 3 Andrew Pinski 2004-07-22 04:04:30 UTC
: Search converges between 2004-03-01-trunk (#446) and 2004-04-01-trunk (#447).
Comment 4 Matt Austern 2004-07-22 21:15:54 UTC
There's no mystery about the cause of this behavior.  It's in cp/decl.c:
	  if (TYPE_ANONYMOUS_P (t))
	    {
	      if (DECL_EXTERN_C_P (decl))
		/* Allow this; it's pretty common in C.  */;
	      else
		{
		  pedwarn ("non-local variable `%#D' uses anonymous type",
			   decl);
		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
		    cp_pedwarn_at ("\
`%#D' does not refer to the unqualified type, so it is not used for linkage",
				   TYPE_NAME (t));
		}
	    }
	  else
	    pedwarn ("non-local variable `%#D' uses local type `%T'",
			decl, t);
cvs annotate shows that this is a change the Geoff made on 04-Mar-04.

The only question is what to do about this change.  Having read the relevant parts of C++03 standard 
and looked at all relevant CWG issues, I believe that 
  struct { int x; } my_global;
is dubious but legal C++.  ("Dubious" becuase I think it's likely to become illegal in some future 
standard.)

So I believe the right solution is to change that first pedwarn to a warning.
Comment 5 Geoff Keating 2004-07-22 22:09:56 UTC
Subject: Re:  [3.5 Regression] [DR 278/132/216/338/389/319] global variables with anonymous types are legal


On 22/07/2004, at 2:15 PM, austern at apple dot com wrote:

>
> ------- Additional Comments From austern at apple dot com  2004-07-22 
> 21:15 -------
> There's no mystery about the cause of this behavior.  It's in 
> cp/decl.c:
> 	  if (TYPE_ANONYMOUS_P (t))
> 	    {
> 	      if (DECL_EXTERN_C_P (decl))
> 		/* Allow this; it's pretty common in C.  */;
> 	      else
> 		{
> 		  pedwarn ("non-local variable `%#D' uses anonymous type",
> 			   decl);
> 		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
> 		    cp_pedwarn_at ("\
> `%#D' does not refer to the unqualified type, so it is not used for 
> linkage",
> 				   TYPE_NAME (t));
> 		}
> 	    }
> 	  else
> 	    pedwarn ("non-local variable `%#D' uses local type `%T'",
> 			decl, t);
> cvs annotate shows that this is a change the Geoff made on 04-Mar-04.
>
> The only question is what to do about this change.  Having read the 
> relevant parts of C++03 standard
> and looked at all relevant CWG issues, I believe that
>   struct { int x; } my_global;
> is dubious but legal C++.  ("Dubious" becuase I think it's likely to 
> become illegal in some future
> standard.)
>
> So I believe the right solution is to change that first pedwarn to a 
> warning.

If this was written

typedef enum { a, b } *p;

static p my_global;

that would be clearly invalid, since 'p' is a name and does have no 
linkage, correct?

So you would really want to use warning only when ! DECL_ORIGINAL_TYPE 
(TYPE_NAME (t)).

Comment 6 Geoff Keating 2004-07-22 22:09:57 UTC
Created attachment 6801 [details]
smime.p7s
Comment 7 Andrew Pinski 2004-09-15 21:22:06 UTC
*** Bug 17511 has been marked as a duplicate of this bug. ***
Comment 8 CVS Commits 2004-09-21 17:24:48 UTC
Subject: Bug 15049

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	austern@gcc.gnu.org	2004-09-21 17:24:45

Modified files:
	gcc/cp         : ChangeLog decl.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/other: anon3.C 

Log message:
	PR c++/15049
	* cp/decl.c (grokvardecl): Accept declarations of global variables
	using anonymous types.
	* testsuite/g++.dg/other/anon3.C: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4372&r2=1.4373
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1300&r2=1.1301
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4326&r2=1.4327
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/other/anon3.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 9 Andrew Pinski 2004-09-21 18:45:38 UTC
Fixed.