summaryrefslogtreecommitdiff
path: root/gcc/ipa-devirt.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-24 19:38:14 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-24 19:38:14 +0000
commit960a55734081e9c372d1db11fb5024de6077adb6 (patch)
treefcafa16d16e0f29657b3cc4999c520546d0e89f1 /gcc/ipa-devirt.c
parent904b56f7344f5146bc2171faf08fad295a363bdc (diff)
downloadgcc-960a55734081e9c372d1db11fb5024de6077adb6.tar.gz
PR lto/66180
* ipa-devirt.c (type_with_linkage): Check that TYPE_STUB_DECL is set; check for assembler name at LTO time. (type_in_anonymous_namespace): Remove hacks, check that all anonymous types are called "<anon>" (odr_type_p): Simplify; add check for "<anon>" (odr_subtypes_equivalent): Add odr_type_p check. * tree.c (need_assembler_name_p): Even anonymous namespace needs assembler name. * mangle.c (mangle_decl): Mangle anonymous namespace types as "<anon>". * g++.dg/lto/pr66180_0.C: New testcase. * g++.dg/lto/pr66180_1.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223633 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r--gcc/ipa-devirt.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 77ecd0d2d83..29438740db3 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -252,9 +252,25 @@ type_with_linkage_p (const_tree t)
{
/* Builtin types do not define linkage, their TYPE_CONTEXT is NULL. */
if (!TYPE_CONTEXT (t)
- || !TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL)
+ || !TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL
+ || !TYPE_STUB_DECL (t))
return false;
+ /* In LTO do not get confused by non-C++ produced types or types built
+ with -fno-lto-odr-type-merigng. */
+ if (in_lto_p)
+ {
+ /* To support -fno-lto-odr-type-merigng recognize types with vtables
+ to have linkage. */
+ if (RECORD_OR_UNION_TYPE_P (t)
+ && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t)))
+ return true;
+ /* Do not accept any other types - we do not know if they were produced
+ by C++ FE. */
+ if (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)))
+ return false;
+ }
+
return (RECORD_OR_UNION_TYPE_P (t)
|| TREE_CODE (t) == ENUMERAL_TYPE);
}
@@ -267,20 +283,22 @@ type_in_anonymous_namespace_p (const_tree t)
{
gcc_assert (type_with_linkage_p (t));
+ /* Keep -fno-lto-odr-type-merging working by recognizing classes with vtables
+ properly into anonymous namespaces. */
+ if (RECORD_OR_UNION_TYPE_P (t)
+ && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t)))
+ return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)));
+
if (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)))
{
- if (DECL_ARTIFICIAL (TYPE_NAME (t)))
- return true;
- tree ctx = DECL_CONTEXT (TYPE_NAME (t));
- while (ctx)
- {
- if (TREE_CODE (ctx) == NAMESPACE_DECL)
- return !TREE_PUBLIC (ctx);
- if (TREE_CODE (ctx) == BLOCK)
- ctx = BLOCK_SUPERCONTEXT (ctx);
- else
- ctx = get_containing_scope (ctx);
- }
+ /* C++ FE uses magic <anon> as assembler names of anonymous types.
+ verify that this match with type_in_anonymous_namespace_p. */
+#ifdef ENABLE_CHECKING
+ if (in_lto_p)
+ gcc_assert (!strcmp ("<anon>",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (t)))));
+#endif
+ return true;
}
return false;
}
@@ -292,14 +310,29 @@ type_in_anonymous_namespace_p (const_tree t)
bool
odr_type_p (const_tree t)
{
- if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
- return true;
/* We do not have this information when not in LTO, but we do not need
to care, since it is used only for type merging. */
gcc_checking_assert (in_lto_p || flag_lto);
- return (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
- && (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))));
+ /* To support -fno-lto-odr-type-merging consider types with vtables ODR. */
+ if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
+ return true;
+
+ if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+ && (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))))
+ {
+#ifdef ENABLE_CHECKING
+ /* C++ FE uses magic <anon> as assembler names of anonymous types.
+ verify that this match with type_in_anonymous_namespace_p. */
+ gcc_assert (!type_with_linkage_p (t)
+ || strcmp ("<anon>",
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (TYPE_NAME (t))))
+ || type_in_anonymous_namespace_p (t));
+#endif
+ return true;
+ }
+ return false;
}
/* Return TRUE if all derived types of T are known and thus
@@ -774,7 +807,7 @@ odr_subtypes_equivalent_p (tree t1, tree t2,
return false;
/* Limit recursion: If subtypes are ODR types and we know
that they are same, be happy. */
- if (!get_odr_type (t1, true)->odr_violated)
+ if (!odr_type_p (t1) || !get_odr_type (t1, true)->odr_violated)
return true;
}