[C++ PATCH] Fix -frepo (PR c++/34178, take 2)

Jakub Jelinek jakub@redhat.com
Wed Dec 5 15:14:00 GMT 2007


On Tue, Nov 27, 2007 at 04:58:31PM -0500, Jakub Jelinek wrote:
> The testcase below doesn't link with -frepo, the static data member
> isn't defined anywhere.
> There are IMHO two separate issues - one is it doesn't make much sense
> to special case any constant expr initialized static data members, only
> const static data members with const expr initialization need to be
> present.  The other is an interaction between repo_emit_p and
> import_export_decl.  In some cases repo_emit_p decides to force emitting
> something, possibly in all compilation units, by returning 2.  But
> that 2 is the same value repo_emit_p returns when -fno-repo.  With
> -fno-repo -fno-implicit-templates we wouldn't want to instantiate e.g.
> the static data member in this case, but when repo_emit_p with -frepo
> (which implies -fno-implicit-templates) decided it should be emitted,
> not emitting it means it won't be in *.rpo either and therefore won't
> be added even during linking.

Turns out I was wrong, even const static data members initialized
outside of the class should be always emitted, as can be seen e.g. on
the new repo7.C testcase I have just posted.  But for non-const static
data members, even when initialized by constant expression we should handle
them normally (i.e. with -frepo just note them in *.rpo and allow them
to be compiled in when linker invokes us again).

Regtested on x86_64-linux, ok for trunk?

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

	PR c++/34178
	* repo.c (repo_emit_p): Return 2 for
	DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P decls only if they are
	const.
	* decl2.c (import_export_decl): Don't make VAR_DECLs import_p when
	flag_use_repository and repo_emit_p returned 2.

	* g++.dg/template/repo6.C: New test.

--- gcc/cp/decl2.c.jj	2007-12-05 13:11:12.000000000 +0100
+++ gcc/cp/decl2.c	2007-12-05 13:37:34.000000000 +0100
@@ -2230,7 +2230,8 @@ import_export_decl (tree decl)
     {
       /* DECL is an implicit instantiation of a function or static
 	 data member.  */
-      if (flag_implicit_templates
+      if ((flag_implicit_templates
+	   && !flag_use_repository)
 	  || (flag_implicit_inline_templates
 	      && TREE_CODE (decl) == FUNCTION_DECL
 	      && DECL_DECLARED_INLINE_P (decl)))
--- gcc/cp/repo.c.jj	2007-12-04 20:33:17.000000000 +0100
+++ gcc/cp/repo.c	2007-12-05 14:40:36.000000000 +0100
@@ -304,11 +304,12 @@ repo_emit_p (tree decl)
 	  && (!TYPE_LANG_SPECIFIC (type)
 	      || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
 	return 2;
-      /* Static data members initialized by constant expressions must
+      /* Const static data members initialized by constant expressions must
 	 be processed where needed so that their definitions are
 	 available.  */
       if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
-	  && DECL_CLASS_SCOPE_P (decl))
+	  && DECL_CLASS_SCOPE_P (decl)
+	  && CP_TYPE_CONST_P (TREE_TYPE (decl)))
 	return 2;
     }
   else if (!DECL_TEMPLATE_INSTANTIATION (decl))
--- gcc/testsuite/g++.dg/template/repo6.C.jj	2007-12-04 20:44:19.000000000 +0100
+++ gcc/testsuite/g++.dg/template/repo6.C	2007-12-04 20:44:19.000000000 +0100
@@ -0,0 +1,25 @@
+// PR c++/34178
+// { dg-options "-frepo" }
+// { dg-final { cleanup-repo-files } }
+// { dg-require-host-local "" }
+
+template<typename T>
+class A
+{
+private:
+  static const int x;
+  static int y;
+
+public:
+  int getX () { return x + y; }
+};
+
+template<typename T> const int A<T>::x = 0;
+template<typename T> int A<T>::y = 0;
+
+int
+main ()
+{
+  A<int> a;
+  return a.getX();
+}


	Jakub



More information about the Gcc-patches mailing list