This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] Patch c++/15049


This fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15049

Previous compilers accepted the construct "enum { x = 3 } x;", but mainline flags it as an error. Based on my reading of the C++ standard and of committee actions on this subject, I believe that our compiler is incorrect. This construct is found in real code, and failing to accept it breaks the build of (among other things) CPU2004.

This is slightly subtle. The incorrect argument in favor of flagging this as an error is that you may not declare a global variable using "a name with no linkage". This argument is incorrect because an anonymous enum isn't "a name with no linkage"; it has no name. The resolution to CWG issue 132 (http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#132) shows that the standards committee was aware of this subtle distinction.

Finally, an admission: this patch still isn't quite right. There are some obscure corner cases that are legal and that the compiler still flags as errors even with my patch. (Exercise for the reader: what are those corner cases?) My only defense is that there aren't any cases where this patch makes things more wrong, and it fixes the cases that people seem to care about in practice.

OK to commit to mainline?

--Matt


? fastjar/fastjar.info Index: gcc/cp/ChangeLog =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v retrieving revision 1.4361 diff -p -r1.4361 ChangeLog *** gcc/cp/ChangeLog 17 Sep 2004 07:01:03 -0000 1.4361 --- gcc/cp/ChangeLog 17 Sep 2004 16:48:58 -0000 *************** *** 1,3 **** --- 1,9 ---- + 2004-09-17 Matt Austern <austern@apple.com> + + PR c++/15049 + * decl.c (grokvardecl): Accept declarations of global variables + using anonymous types. + 2004-09-16 Mark Mitchell <mark@codesourcery.com>

  	PR c++/16002
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1296
diff -p -r1.1296 decl.c
*** gcc/cp/decl.c	16 Sep 2004 09:53:36 -0000	1.1296
--- gcc/cp/decl.c	17 Sep 2004 16:48:58 -0000
*************** grokvardecl (tree type,
*** 5892,5908 ****
  	 or enumeration declared in a local scope) shall not be used to
  	 declare an entity with linkage.

! 	 Only check this for public decls for now.  */
!       tree t = no_linkage_check (TREE_TYPE (decl),
! 				 /*relaxed_p=*/false);
        if (t)
  	{
  	  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)))
--- 5892,5922 ----
  	 or enumeration declared in a local scope) shall not be used to
  	 declare an entity with linkage.

! 	 Only check this for public decls for now.
!
! 	 Note that this does not forbid "enum { a = 3 } x;".  The enum
! 	 in question is not "a name with no linkage", because it has no
! 	 name.  However, "typedef enum {a = 3 } *p; p x;" is ill formed
! 	 because p is a name with no linkage.
!
! 	 The status of this construct is clear in C++03 (see closed
! 	 CWG issue 132), but it may be revised in C++0x (see open
! 	 CWG issue 389 and related issues). */
!
!       tree t1 = TREE_TYPE (decl);
!       tree t = no_linkage_check (t1, /*relaxed_p=*/false);
        if (t)
  	{
  	  if (TYPE_ANONYMOUS_P (t))
  	    {
! 	      if (DECL_EXTERN_C_P (decl)
! 		/* Allow this; it's pretty common in C.  */
! 		  || same_type_ignoring_top_level_qualifiers_p(t1, t))
! 		/* Allow anonymous types; see above. */
! 		;
  	      else
  		{
+ 		  /* It's a typedef referring to an anonymous type. */
  		  pedwarn ("non-local variable `%#D' uses anonymous type",
  			   decl);
  		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
Index: gcc/testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.4306
diff -p -r1.4306 ChangeLog
*** gcc/testsuite/ChangeLog	17 Sep 2004 13:48:34 -0000	1.4306
--- gcc/testsuite/ChangeLog	17 Sep 2004 16:48:59 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 	2004-09-17  Matt Austern  <austern@apple.com>
+
+ 	PR c++/15049
+ 	* g++.dg/other/anon3.C: New.
+ 	
  2004-09-17  David Edelsohn  <edelsohn@gnu.org>

  	* gcc.dg/darwin-longlong.c: XFAIL on AIX and SPE.
Index: gcc/testsuite/g++.dg/other/anon3.C
===================================================================
RCS file: gcc/testsuite/g++.dg/other/anon3.C
diff -N gcc/testsuite/g++.dg/other/anon3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/other/anon3.C	17 Sep 2004 16:49:01 -0000
***************
*** 0 ****
--- 1,7 ----
+ // pr c++/15049
+ // Origin: Matt Austern <austern@apple.com>
+ // Test that we can declare a global variable whose type is anonymous.
+
+ // { dg-do compile }
+
+ enum { a = 3 } x;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]