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]

Re: [C++ PATCH] Diagnose static data members in anon ns which are used, but weren't defined (PR c++/34094)


On Wed, Nov 21, 2007 at 10:44:26AM -0500, Jason Merrill wrote:
> Jakub Jelinek wrote:
> >The important difference is DECL_EXTERNAL, but as it is
> >DECL_NOT_REALLY_EXTERN, cp_wrap_global_declarations wants to clear that.
> >DECL_NONLOCAL is a FE private flag in this case.
> 
> >Instead of issuing the error we could just not set DECL_EXTERNAL for it:
> 
> >+         if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl)
> >+             && !(TREE_CODE (decl) == VAR_DECL
> >+                   && DECL_NONLOCAL (decl)
> >+                   && DECL_CLASS_SCOPE_P (decl)
> >+                   && DECL_INITIAL (decl) == NULL_TREE
> >+                   && type_visibility (DECL_CONTEXT (decl)) == 
> >VISIBILITY_ANON))
> 
> A static data member that has not yet been defined out-of-class has 
> DECL_IN_AGGR_P set.  In that case, we should leave DECL_EXTERNAL set.  I 
> don't think we need the other tests.
> 
> > But it is hard to have a g++.dg testcase
> >for that, plus I thought when the compiler can detect the bug, it is better
> >to report it than to leave it for ld.
> 
> Sure.  If we're leaving DECL_EXTERNAL set, and the static data member is 
> !TREE_PUBLIC (and DECL_INITIAL is NULL_TREE) it makes sense to complain 
> like we do for static functions that are declared but not defined.

So is this better?  When we issue error, it doesn't matter much whether
the var is emitted into assembly or not, and if we don't, then we might
report this several times (cp_write_global_declarations sometimes decides
to reconsider and repeats the loop).  I'm not sure !TREE_PUBLIC
check is needed, if it is not defined in the current CU and wasn't in
anon namespace, it wouldn't be DECL_NOT_REALLY_EXTERN and thus we wouldn't
hit this code at all.

Bootstrapped/regtested on x86_64-linux.

2007-11-21  Jakub Jelinek  <jakub@redhat.com>

	PR c++/34094
	* decl2.c (cp_write_global_declarations): Issue error about static
	data members in anonymous namespace which are declared and used,
	but not defined.

	* g++.dg/ext/visibility/anon7.C: New test.

--- gcc/cp/decl2.c.jj	2007-11-06 09:15:15.000000000 +0100
+++ gcc/cp/decl2.c	2007-11-21 17:30:53.000000000 +0100
@@ -3365,7 +3365,12 @@ cp_write_global_declarations (void)
 	  /* If this static data member is needed, provide it to the
 	     back end.  */
 	  if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
-	    DECL_EXTERNAL (decl) = 0;
+	    {
+	      if (DECL_IN_AGGR_P (decl) && DECL_INITIAL (decl) == NULL_TREE)
+		error ("%Jstatic data member %qD used, but not defined",
+		       decl, decl);
+	      DECL_EXTERNAL (decl) = 0;
+	    }
 	}
       if (VEC_length (tree, pending_statics) != 0
 	  && wrapup_global_declarations (VEC_address (tree, pending_statics),
--- gcc/testsuite/g++.dg/ext/visibility/anon7.C.jj	2007-11-20 19:03:19.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/visibility/anon7.C	2007-11-20 19:12:40.000000000 +0100
@@ -0,0 +1,23 @@
+// PR c++/34094
+// { dg-do compile }
+
+namespace
+{
+  struct A {
+    static int bar ();
+    static int i;		// { dg-error "used, but not defined" }
+    static int j;
+    static int k;
+    static int l;
+    static const int m = 16;
+    static const int n = 17;
+  };
+  int A::j = 4;
+  int A::k;
+  const int A::m;
+}
+
+int foo (void)
+{
+  return A::i + A::j + A::k + A::m + A::n + A::bar ();
+}


	Jakub


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