re PR c++/42608 (Undefined reference not reported in case of explicit template instan...
authorJakub Jelinek <jakub@redhat.com>
Thu, 14 Jan 2010 22:41:02 +0000 (23:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 14 Jan 2010 22:41:02 +0000 (23:41 +0100)
PR c++/42608
* varasm.c (declare_weak): Add weak attribute to decl if it
doesn't have one already.
(assemble_external): Only add decls to weak_decls if they also
have weak attribute.

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

From-SVN: r155919

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/instantiate11.C [new file with mode: 0644]
gcc/varasm.c

index ce49f3683a6bda62eb36b7abc78f37f0d0032da9..29f71b12d14678e818a0e5258888b529f4af0917 100644 (file)
@@ -1,3 +1,11 @@
+2010-01-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/42608
+       * varasm.c (declare_weak): Add weak attribute to decl if it
+       doesn't have one already.
+       (assemble_external): Only add decls to weak_decls if they also
+       have weak attribute.
+
 2010-01-14  Alexandre Oliva  <aoliva@redhat.com>
 
        * var-tracking.c (var_reg_delete): Don't delete the association
index 7c89ccde3bdeb83610c7a64477933f96e4d1b945..5b284490686b2f1a25638e96b5558d294fc45f47 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/42608
+       * g++.dg/template/instantiate11.C: New test.
+
 2010-01-14  Jason Merrill  <jason@redhat.com>
 
        PR c++/42701
diff --git a/gcc/testsuite/g++.dg/template/instantiate11.C b/gcc/testsuite/g++.dg/template/instantiate11.C
new file mode 100644 (file)
index 0000000..3598d58
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/42608
+// { dg-do compile }
+
+template <class U, class V>
+struct A;
+
+template <class V>
+struct A<int, V>
+{
+  void f ();
+};
+
+template struct A<int, int>;
+
+int
+main ()
+{
+  A<int, int> a;
+  a.f ();
+  return 0;
+}
+
+// Make sure we get undefined reference error if
+// A<int, int>::f () isn't instantiated elsewhere.
+// { dg-final { scan-assembler-not "weak\[\n\t\]*_ZN1AIiiE1fEv" } }
index fab62198053ad0d0c42375a05d0de48b9bdc3b26..7ed59055745b6d13fc7f1403412b0f468d3e9b46 100644 (file)
@@ -2337,13 +2337,15 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
   /* We want to output annotation for weak and external symbols at
      very last to check if they are references or not.  */
 
-  if (SUPPORTS_WEAK && DECL_WEAK (decl)
+  if (SUPPORTS_WEAK
+      && DECL_WEAK (decl)
       /* TREE_STATIC is a weird and abused creature which is not
         generally the right test for whether an entity has been
         locally emitted, inlined or otherwise not-really-extern, but
         for declarations that can be weak, it happens to be
         match.  */
       && !TREE_STATIC (decl)
+      && lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
       && value_member (decl, weak_decls) == NULL_TREE)
     weak_decls = tree_cons (NULL, decl, weak_decls);
 
@@ -5227,6 +5229,9 @@ declare_weak (tree decl)
     warning (0, "weak declaration of %q+D not supported", decl);
 
   mark_weak (decl);
+  if (!lookup_attribute ("weak", DECL_ATTRIBUTES (decl)))
+    DECL_ATTRIBUTES (decl)
+      = tree_cons (get_identifier ("weak"), NULL, DECL_ATTRIBUTES (decl));
 }
 
 static void