This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
reject vars whose types have no linkage
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 17 Feb 2005 19:06:04 -0200
- Subject: reject vars whose types have no linkage
- Organization: Red Hat Global Engineering Services Compiler Team
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 <aoliva@redhat.com>
* 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. */
- ;
else
{
- /* 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",
decl);
if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
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 <aoliva@redhat.com>
* 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 http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}