diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-24 19:38:14 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-24 19:38:14 +0000 |
commit | 960a55734081e9c372d1db11fb5024de6077adb6 (patch) | |
tree | fcafa16d16e0f29657b3cc4999c520546d0e89f1 /gcc/ipa-devirt.c | |
parent | 904b56f7344f5146bc2171faf08fad295a363bdc (diff) | |
download | gcc-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.c | 69 |
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; } |