From: Jason Merrill Date: Wed, 10 Sep 2014 17:28:59 +0000 (-0400) Subject: re PR ipa/61659 (Extra undefined symbol because of devirtualization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ca78482dcdf0dc76fca1334673cd43f7108d8338;p=gcc.git re PR ipa/61659 (Extra undefined symbol because of devirtualization) 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. From-SVN: r215134 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ae54a68b73a..565b940f0be 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-09-10 Jason Merrill + + 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. + 2014-09-08 Jason Merrill * typeck.c (build_class_member_access_expr): Move diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d8fb35e2123..6e195bb803d 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 44569e23b1f..3c9317883ee 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 00000000000..663643f3e96 --- /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 static void g() +{ + static int i; + ++i; +} + +int main() +{ + f(); + g(); +}