aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-09-10 13:28:59 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-09-10 13:28:59 -0400
commitca78482dcdf0dc76fca1334673cd43f7108d8338 (patch)
treeb5d3bab44fd34ec4fd6249130ae736e4d7dd2b75
parent1c22488e18f254dde889e01c72f250be41b9227e (diff)
downloadgcc-ca78482dcdf0dc76fca1334673cd43f7108d8338.zip
gcc-ca78482dcdf0dc76fca1334673cd43f7108d8338.tar.gz
gcc-ca78482dcdf0dc76fca1334673cd43f7108d8338.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl.c9
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/testsuite/g++.dg/abi/no-weak1.C21
4 files changed, 38 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ae54a68..565b940 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2014-09-10 Jason Merrill <jason@redhat.com>
+
+ 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 <jason@redhat.com>
* typeck.c (build_class_member_access_expr): Move
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 44569e23..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>();
+}