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] Fix regressions introduced by my PR34094 fix (PR c++/34238, c++/34340)


Hi!

Over time more problems with PR34094 fix have been reported, they are
summarized in the testcases below.
The following patch (which obsoletes my earlier 34238 patch) fixes all of
this, but letting cgraph_optimize actually emit all the vars into assembly
and only checking afterwards if we emitted something we shouldn't, which
seems to be much more reliable.
We still need to special case static data members initialized in the class,
because at least ATM sometimes such decls are emitted into assembly even if
they e.g. are just used through value (and thus not needed), while their
address wasn't taken etc., and we need to use for that
DECL_INITIALIZED_IN_CLASS_P test rather than check for non-NULL
DECL_INITIAL, because in templates even when initialized in class
DECL_INITIAL is often NULL.

Regtested on x86_64-linux, ok for trunk?

2007-12-05  Jakub Jelinek  <jakub@redhat.com>

	PR c++/34238
	PR c++/34340
	* decl2.c (cp_write_global_declarations): Move diagnostics about
	static data member used, but not defined, after cgraph_optimize,
	error only for decls that have been written and weren't
	DECL_INITIALIZED_IN_CLASS_P.

	* g++.dg/ext/visibility/anon9.C: New test.
	* g++.dg/ext/visibility/anon10.C: New test.
	* g++.dg/ext/visibility/repo7.C: New test.

--- gcc/cp/decl2.c.jj	2007-12-04 20:33:17.000000000 +0100
+++ gcc/cp/decl2.c	2007-12-05 13:37:34.000000000 +0100
@@ -3365,21 +3365,7 @@ 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))
-	    {
-	      /* Error on
-		 namespace { struct A { static int i; }; }
-		 int foo () { return A::i; }
-		 without A::i definition (which can't be defined in
-		 a different CU because of the anonymous namespace).
-		 Don't do this if DECL_INITIAL is set, because for
-		 namespace { struct A { static const int i = 4; } };
-		 decl_needed_p won't reliably detect whether it was
-		 really needed.  */
-	      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;
-	    }
+	    DECL_EXTERNAL (decl) = 0;
 	}
       if (VEC_length (tree, pending_statics) != 0
 	  && wrapup_global_declarations (VEC_address (tree, pending_statics),
@@ -3450,6 +3436,21 @@ cp_write_global_declarations (void)
 				 VEC_length (tree, pending_statics));
       emit_debug_global_declarations (VEC_address (tree, pending_statics),
 				      VEC_length (tree, pending_statics));
+      /* Error on
+	 namespace { struct A { static int i; }; }
+	 int foo () { return A::i; }
+	 without A::i definition (which can't be defined in
+	 a different CU because of the anonymous namespace).
+	 Don't do this if DECL_INITIALIZED_IN_CLASS_P is set, because for
+	 namespace { struct A { static const int i = 4; } };
+	 we won't reliably detect whether it was really needed
+	 and the definition couldn't provide different value than
+	 the initialized in class anyway.  */
+      for (i = 0; VEC_iterate (tree, pending_statics, i, decl); ++i)
+	if (DECL_IN_AGGR_P (decl)
+	    && TREE_ASM_WRITTEN (decl)
+	    && !DECL_INITIALIZED_IN_CLASS_P (decl))
+	  error ("%Jstatic data member %qD used, but not defined", decl, decl);
     }
 
   /* Generate hidden aliases for Java.  */
--- gcc/testsuite/g++.dg/ext/visibility/anon9.C.jj	2007-12-04 20:44:19.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/visibility/anon9.C	2007-12-04 20:44:19.000000000 +0100
@@ -0,0 +1,11 @@
+// PR c++/34238
+// { dg-do compile }
+
+namespace
+{
+  template <typename T = int> struct A
+  {
+    static const bool a = true;
+  };
+}
+struct A<> a;
--- gcc/testsuite/g++.dg/ext/visibility/anon10.C.jj	2007-12-05 15:07:46.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/visibility/anon10.C	2007-12-05 15:05:16.000000000 +0100
@@ -0,0 +1,44 @@
+// http://bugzilla.redhat.com/411871
+// { dg-do compile }
+
+extern "C" int printf (const char *, ...);
+
+struct E
+{
+  template <typename T> E (const volatile T&);
+  template <typename T> E (T&);
+  char x[64];
+};
+
+template<typename T> struct D
+{
+  static E foo (E, ...);
+  static int foo (T, int);
+};
+
+template<typename T, typename U> struct C
+{
+  static T ca;
+  static const int value = sizeof (D<U>::foo (ca, 0)) == sizeof (int);
+};
+
+struct A
+{
+  int a;
+};
+
+namespace
+{
+  struct B
+  {
+    int a;
+  };
+}
+
+int bar (void)
+{
+  C<A, int> a;
+  C<B, int> b;
+
+  return a.value + b.value;
+}
--- gcc/testsuite/g++.dg/template/repo7.C.jj	2007-12-05 13:46:47.000000000 +0100
+++ gcc/testsuite/g++.dg/template/repo7.C	2007-12-05 13:46:35.000000000 +0100
@@ -0,0 +1,29 @@
+// PR c++/34340
+// { dg-options "-frepo" }
+// { dg-final { cleanup-repo-files } }
+// { dg-require-host-local "" }
+
+struct A
+{
+  int a;
+};
+
+struct B
+{
+  static const A b;
+};
+
+template <typename T> struct D : public T
+{
+  static const A b;
+};
+
+const A B::b = { 1 };
+
+template<typename T> const A D<T>::b = { 2 };
+template class D<B>;
+
+int
+main ()
+{
+}

	Jakub


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