After * decl.c (maybe_commonize_var): Don't use DECL_COMDAT to trigger comdat_linkage.
targets without weak symbol support started getting link errors bootstrapping GCC. This ought to fix that.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit e3859ec10649526a24b439301db79a34d7b90ba3 Author: Jason Merrill <ja...@redhat.com> Date: Tue Sep 9 12:21:03 2014 -0400 PR c++/61659 * decl.c (grokfndecl): Don't set DECL_COMDAT on static inlines. (duplicate_decls, start_decl): Likewise. * pt.c (check_explicit_specialization): Likewise. (push_template_decl_real): Or static templates. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d8fb35e..6e195bb 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2215,7 +2215,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) olddecl); SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); - DECL_COMDAT (newdecl) = DECL_DECLARED_INLINE_P (newdecl); + DECL_COMDAT (newdecl) = (TREE_PUBLIC (newdecl) + && DECL_DECLARED_INLINE_P (newdecl)); /* Don't propagate visibility from the template to the specialization here. We'll do that in determine_visibility if @@ -4718,7 +4719,8 @@ start_decl (const cp_declarator *declarator, { SET_DECL_TEMPLATE_SPECIALIZATION (decl); if (TREE_CODE (decl) == FUNCTION_DECL) - DECL_COMDAT (decl) = DECL_DECLARED_INLINE_P (decl); + DECL_COMDAT (decl) = (TREE_PUBLIC (decl) + && DECL_DECLARED_INLINE_P (decl)); else DECL_COMDAT (decl) = false; @@ -7699,7 +7701,8 @@ grokfndecl (tree ctype, if (inlinep) { DECL_DECLARED_INLINE_P (decl) = 1; - DECL_COMDAT (decl) = 1; + if (publicp) + DECL_COMDAT (decl) = 1; } if (inlinep & 2) DECL_DECLARED_CONSTEXPR_P (decl) = true; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 44569e2..3c93178 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2813,7 +2813,8 @@ check_explicit_specialization (tree declarator, SET_DECL_IMPLICIT_INSTANTIATION (decl); else if (TREE_CODE (decl) == FUNCTION_DECL) /* A specialization is not necessarily COMDAT. */ - DECL_COMDAT (decl) = DECL_DECLARED_INLINE_P (decl); + DECL_COMDAT (decl) = (TREE_PUBLIC (decl) + && DECL_DECLARED_INLINE_P (decl)); else if (TREE_CODE (decl) == VAR_DECL) DECL_COMDAT (decl) = false; @@ -5059,6 +5060,7 @@ template arguments to %qD do not match original template %qD", if (flag_implicit_templates && !is_friend + && TREE_PUBLIC (decl) && VAR_OR_FUNCTION_DECL_P (decl)) /* Set DECL_COMDAT on template instantiations; if we force them to be emitted by explicit instantiation or -frepo, diff --git a/gcc/testsuite/g++.dg/abi/no-weak1.C b/gcc/testsuite/g++.dg/abi/no-weak1.C new file mode 100644 index 0000000..663643f --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/no-weak1.C @@ -0,0 +1,21 @@ +// { dg-options "-fno-weak" } +// { dg-final { scan-assembler "local\[ \t\]*_ZZL1fvE1i" { target x86_64-*-*gnu } } } +// { dg-final { scan-assembler "local\[ \t\]*_ZZ1gIiEvvE1i" { target x86_64-*-*gnu } } } + +static inline void f() +{ + static int i; + ++i; +}; + +template <class T> static void g() +{ + static int i; + ++i; +} + +int main() +{ + f(); + g<int>(); +}