From 5b1cbe1453663b9abd6df089c2882071f2335fb2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 14 Jan 2010 23:41:02 +0100 Subject: [PATCH] re PR c++/42608 (Undefined reference not reported in case of explicit template instantiation) 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 | 8 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/template/instantiate11.C | 25 +++++++++++++++++++ gcc/varasm.c | 7 +++++- 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/instantiate11.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce49f3683a6..29f71b12d14 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-01-14 Jakub Jelinek + + 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 * var-tracking.c (var_reg_delete): Don't delete the association diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c89ccde3bd..5b284490686 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-01-14 Jakub Jelinek + + PR c++/42608 + * g++.dg/template/instantiate11.C: New test. + 2010-01-14 Jason Merrill 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 index 00000000000..3598d5890bf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate11.C @@ -0,0 +1,25 @@ +// PR c++/42608 +// { dg-do compile } + +template +struct A; + +template +struct A +{ + void f (); +}; + +template struct A; + +int +main () +{ + A a; + a.f (); + return 0; +} + +// Make sure we get undefined reference error if +// A::f () isn't instantiated elsewhere. +// { dg-final { scan-assembler-not "weak\[\n\t\]*_ZN1AIiiE1fEv" } } diff --git a/gcc/varasm.c b/gcc/varasm.c index fab62198053..7ed59055745 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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 -- 2.30.2