This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix -frepo (PR c++/34178, take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>, Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 5 Dec 2007 10:11:20 -0500
- Subject: [C++ PATCH] Fix -frepo (PR c++/34178, take 2)
- References: <20071127215831.GX16835@devserv.devel.redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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