This is the mail archive of the 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]

reject vars whose types have no linkage

We have code to do that already, but it's broken.

It accepts:

struct { int i; } a;

which g++.dg/lookup/anon2.C was meant to catch but ended up not
catching due to the unrelated access control error, and it rejects:

struct { int i; } a[1];

The problem in grokvardecl is that it only accepts declarations whose
types match the type returned by no_linkage_check(), and
no_linkage_check() will descend into components of compound types and
possibly return them.  So direct uses of a type are allowed, whereas
indirect uses aren't.

The relevant DRs seem to all point towards rejecting such code.  Since
-fpermissive is always an option to let pedwarns through, I thought
we'd be better off rejecting both, as per the current DR resolutions.

Ok to install?  Testing on x86_64-linux-gnu

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <>
	* decl.c (grokvardecl): Don't exempt anonymous types from having
	linkage for variables that have linkage other than "C".

Index: gcc/cp/decl.c
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1364
diff -u -p -r1.1364 decl.c
--- gcc/cp/decl.c 14 Feb 2005 13:45:25 -0000 1.1364
+++ gcc/cp/decl.c 17 Feb 2005 21:01:02 -0000
@@ -5930,8 +5930,7 @@ grokvardecl (tree type,
 	 declare an entity with linkage.
 	 Only check this for public decls for now.  */
-      tree t1 = TREE_TYPE (decl);
-      tree t = no_linkage_check (t1, /*relaxed_p=*/false);
+      tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
       if (t)
 	  if (TYPE_ANONYMOUS_P (t))
@@ -5939,24 +5938,16 @@ grokvardecl (tree type,
 	      if (DECL_EXTERN_C_P (decl))
 		/* Allow this; it's pretty common in C.  */
-	      else if (same_type_ignoring_top_level_qualifiers_p(t1, t))
-	        /* This is something like "enum { a = 3 } x;", which is
-		   well formed.  The enum doesn't have "a name with no
-		   linkage", because it has no name.  See closed CWG issue
-		   132.
-		   Note that while this construct is well formed in C++03
-		   it is likely to become ill formed in C++0x.  See open
-		   CWG issue 389 and related issues.  */
-		;
-		  /* It's a typedef referring to an anonymous type.  */
+		  /* DRs 132, 319 and 389 seem to indicate types with
+		     no linkage can only be used to declare extern "C"
+		     entities.  */
 		  pedwarn ("non-local variable %q#D uses anonymous type",
 		    cp_pedwarn_at ("%q#D does not refer to the unqualified "
-                                   "type, so it is not used for linkage",
+				   "type, so it is not used for linkage",
 				   TYPE_NAME (t));
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <>
	* g++.dg/lookup/anon2.C: Don't let access checks make it look like
	the test passes.

Index: gcc/testsuite/g++.dg/lookup/anon2.C
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/lookup/anon2.C,v
retrieving revision 1.2
diff -u -p -r1.2 anon2.C
--- gcc/testsuite/g++.dg/lookup/anon2.C 4 Mar 2004 22:42:59 -0000 1.2
+++ gcc/testsuite/g++.dg/lookup/anon2.C 17 Feb 2005 21:01:15 -0000
@@ -1,6 +1,9 @@
 // { dg-do compile }
 // { dg-options "" }
-class { int i; } a; // { dg-error "private|anonymous type" }
-void foo() { a.i; } // { dg-error "context" }
+// Make sure we issue a diagnostic if a type with no linkage is used
+// to declare a a variable that has linkage.
+struct { int i; } a; // { dg-error "anonymous type" }
+void foo() { a.i; }
Alexandre Oliva   
Red Hat Compiler Engineer   aoliva@{,}
Free Software Evangelist  oliva@{,}

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