This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Only emit .weak for externs that have weak attribute or pragma weak (PR c++/42608)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 8 Jan 2010 18:52:37 -0500
- Subject: [PATCH] Only emit .weak for externs that have weak attribute or pragma weak (PR c++/42608)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This got broken by a change for LTO, which moved queuing of decls into
weak_decls chain from declare_weak to assemble_external. declare_weak is
called just for real weak attribute, pragma weak, darwin weak_import
or something in Ada and we only want .weak for externs in those cases,
not for DECL_WEAK set because of weakref attribute or C++ vague linkage.
The following patch fixes it by making sure the decl has weak attribute
(for weak attribute that's no change, just for #pragma weak or weak_import),
and only adding to weak_decls decls that have that attribute.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2010-01-09 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.
* g++.dg/template/instantiate11.C: New test.
--- gcc/varasm.c.jj 2009-11-09 16:38:29.000000000 +0100
+++ gcc/varasm.c 2010-01-08 13:30:12.000000000 +0100
@@ -2337,13 +2337,15 @@ assemble_external (tree decl ATTRIBUTE_U
/* 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
--- gcc/testsuite/g++.dg/template/instantiate11.C.jj 2010-01-08 13:48:58.000000000 +0100
+++ gcc/testsuite/g++.dg/template/instantiate11.C 2010-01-08 14:18:44.000000000 +0100
@@ -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" } }
Jakub