re PR c++/36364 (Problem with -frepo)
authorJakub Jelinek <jakub@redhat.com>
Fri, 27 Jun 2008 22:26:48 +0000 (00:26 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 27 Jun 2008 22:26:48 +0000 (00:26 +0200)
PR c++/36364
* repo.c (repo_emit_p): Put const static data members initialized
by const expr into *.rpo file, just return 2 if IDENTIFIER_REPO_CHOSEN
for it is 0.

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

From-SVN: r137205

gcc/cp/ChangeLog
gcc/cp/repo.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/repo9.C [new file with mode: 0644]

index e2368b462ce73dde0887a99dad543c1777f16781..14d08aca504af86bd8c8ebfd3fcb421689ae4822 100644 (file)
@@ -1,3 +1,10 @@
+2008-06-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/36364
+       * repo.c (repo_emit_p): Put const static data members initialized
+       by const expr into *.rpo file, just return 2 if IDENTIFIER_REPO_CHOSEN
+       for it is 0.
+
 2008-06-27  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/36655
index 1fe96a2dddedabffe9f3a8dde93b5e788def2c6c..b53062dfe8f44ace0b98f800304f69df754438dc 100644 (file)
@@ -280,6 +280,7 @@ finish_repo (void)
 int
 repo_emit_p (tree decl)
 {
+  int ret = 0;
   gcc_assert (TREE_PUBLIC (decl));
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
              || TREE_CODE (decl) == VAR_DECL);
@@ -306,10 +307,12 @@ repo_emit_p (tree decl)
        return 2;
       /* Const static data members initialized by constant expressions must
         be processed where needed so that their definitions are
-        available.  */
+        available.  Still record them into *.rpo files, so if they
+        weren't actually emitted and collect2 requests them, they can
+        be provided.  */
       if (DECL_INTEGRAL_CONSTANT_VAR_P (decl)
          && DECL_CLASS_SCOPE_P (decl))
-       return 2;
+       ret = 2;
     }
   else if (!DECL_TEMPLATE_INSTANTIATION (decl))
     return 2;
@@ -343,7 +346,7 @@ repo_emit_p (tree decl)
       pending_repo = tree_cons (NULL_TREE, decl, pending_repo);
     }
 
-  return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl));
+  return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
 }
 
 /* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
index 6d739ff152b46953987222db12d7aae5cfad8fd1..d0d635d3357e46f11d791c80c0a95663607b387e 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/36364
+       * g++.dg/template/repo9.C: New test.
+
 2008-06-27  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/36655
diff --git a/gcc/testsuite/g++.dg/template/repo9.C b/gcc/testsuite/g++.dg/template/repo9.C
new file mode 100644 (file)
index 0000000..f55024c
--- /dev/null
@@ -0,0 +1,48 @@
+// PR c++/36364
+// { dg-options "-frepo" }
+// { dg-final { cleanup-repo-files } }
+// { dg-require-host-local "" }
+
+template <typename C> struct A
+{
+  static void assign (C &c1, const C &c2) { c1 = c2; }
+};
+
+template <typename C, typename T> struct B
+{
+  struct D
+  {
+    static const C terminal;
+    static unsigned long stor[];
+    static D &empty_rep ()
+    {
+      void *p = reinterpret_cast <void *>(&stor);
+      return *reinterpret_cast <D *>(p);
+    }
+    void test (unsigned long n)
+    {
+      T::assign (this->refdata ()[n], terminal);
+    }
+    C *refdata () throw ()
+    {
+      return reinterpret_cast <C *>(this + 1);
+    }
+  };
+  C *dataplus;
+  C *data () const { return dataplus; }
+  D *rep () const { return &((reinterpret_cast < D * >(data ()))[-1]); }
+  static D & empty_rep () { return D::empty_rep (); }
+  B () : dataplus (empty_rep ().refdata ()) { }
+  ~B () { }
+  void push_back (C c) { rep ()->test (10); }
+};
+
+template <typename C, typename T> const C B <C, T>::D::terminal = C ();
+template <typename C, typename T> unsigned long B <C, T>::D::stor[64];
+
+int
+main ()
+{
+  B <char, A <char> > s;
+  s.push_back ('a');
+}