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)
- 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: Tue, 27 Nov 2007 16:58:31 -0500
- Subject: [C++ PATCH] Fix -frepo (PR c++/34178)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
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.
Following was bootstrapped/regtested on x86_64-linux, ok for trunk?
2007-11-27 Jakub Jelinek <jakub@redhat.com>
PR c++/34178
* repo.c (repo_emit_p): Return 2 for DECL_INTEGRAL_CONSTANT_VAR_P
in class scope rather than DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
* 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/repo.c.jj 2007-08-27 10:15:32.000000000 +0200
+++ gcc/cp/repo.c 2007-11-27 20:02:57.000000000 +0100
@@ -304,10 +304,10 @@ 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)
+ if (DECL_INTEGRAL_CONSTANT_VAR_P (decl)
&& DECL_CLASS_SCOPE_P (decl))
return 2;
}
--- gcc/cp/decl2.c.jj 2007-11-26 22:19:54.000000000 +0100
+++ gcc/cp/decl2.c 2007-11-27 20:21:57.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/testsuite/g++.dg/template/repo6.C.jj 2007-11-27 20:59:36.000000000 +0100
+++ gcc/testsuite/g++.dg/template/repo6.C 2007-11-27 20:59:29.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