diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-05-24 21:38:14 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-05-24 19:38:14 +0000 |
commit | 233ce289250944dde071638799f9ba1a51a0a9bf (patch) | |
tree | fcafa16d16e0f29657b3cc4999c520546d0e89f1 /gcc | |
parent | bc0c7f396b0c9648365aee462e25107db00227e8 (diff) | |
download | gcc-233ce289250944dde071638799f9ba1a51a0a9bf.zip gcc-233ce289250944dde071638799f9ba1a51a0a9bf.tar.gz gcc-233ce289250944dde071638799f9ba1a51a0a9bf.tar.bz2 |
re PR lto/66180 (many -Wodr false positives when building LLVM with -flto)
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.
From-SVN: r223633
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 15 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 69 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr66180_0.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr66180_1.C | 11 | ||||
-rw-r--r-- | gcc/tree.c | 3 |
8 files changed, 114 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33f5865..ac03017 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2015-05-22 Jan Hubicka <hubicka@ucw.cz> + 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. + +2015-05-22 Jan Hubicka <hubicka@ucw.cz> + * ipa-utils.h (method_class_type): Remove. * cgraphunit.c (walk_polymorphic_call_targets): Use TYPE_METHOD_BASETYPE. * ipa-devirt.c (type_in_anonymous_namespace_p): Check that it is called diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 35d5f34..b5168c2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-05-22 Jan Hubicka <hubicka@ucw.cz> + + PR lto/66180 + * mangle.c (mangle_decl): Mangle anonymous namespace types as + "<anon>". + 2015-05-23 Nathan Sidwell <nathan@acm.org> PR c++/65936 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 647ec70..aa466cd 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3511,7 +3511,20 @@ mangle_decl (const tree decl) if (dep) return; - id = get_mangled_id (decl); + /* During LTO we keep mangled names of TYPE_DECLs for ODR type merging. + It is not needed to assign names to anonymous namespace, but we use the + "<anon>" marker to be able to tell if type is C++ ODR type or type + produced by other language. */ + if (TREE_CODE (decl) == TYPE_DECL + && TYPE_STUB_DECL (TREE_TYPE (decl)) + && !TREE_PUBLIC (TYPE_STUB_DECL (TREE_TYPE (decl)))) + id = get_identifier ("<anon>"); + else + { + gcc_assert (TREE_CODE (decl) != TYPE_DECL + || !no_linkage_check (TREE_TYPE (decl), true)); + id = get_mangled_id (decl); + } SET_DECL_ASSEMBLER_NAME (decl, id); if (G.need_abi_warning diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 77ecd0d..2943874 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 41a478d..7e6122d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-05-22 Jan Hubicka <hubicka@ucw.cz> + + PR lto/66180 + * g++.dg/lto/pr66180_0.C: New testcase. + * g++.dg/lto/pr66180_1.C: New testcase. + 2015-05-24 Mikael Morin <mikael@gcc.gnu.org> PR fortran/66257 diff --git a/gcc/testsuite/g++.dg/lto/pr66180_0.C b/gcc/testsuite/g++.dg/lto/pr66180_0.C new file mode 100644 index 0000000..c22dc28 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr66180_0.C @@ -0,0 +1,13 @@ +// { dg-lto-do link } +// { dg-lto-options { { -flto -std=c++14 -r -nostdlib } } } +#include <memory> +namespace { +class A { + int i; +}; +} +class G { + std::unique_ptr<A> foo() const; +}; +std::unique_ptr<A> G::foo() const { return std::make_unique<A>(); } + diff --git a/gcc/testsuite/g++.dg/lto/pr66180_1.C b/gcc/testsuite/g++.dg/lto/pr66180_1.C new file mode 100644 index 0000000..a4deb96 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr66180_1.C @@ -0,0 +1,11 @@ +#include <memory> +namespace { +class A { + bool a; +}; +} +class H { + std::unique_ptr<A> bar() const; +}; +std::unique_ptr<A> H::bar() const { return std::make_unique<A>(); } + @@ -5182,8 +5182,7 @@ need_assembler_name_p (tree decl) && DECL_NAME (decl) && decl == TYPE_NAME (TREE_TYPE (decl)) && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) - && ((type_with_linkage_p (TREE_TYPE (decl)) - && !type_in_anonymous_namespace_p (TREE_TYPE (decl))) + && (type_with_linkage_p (TREE_TYPE (decl)) || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE) && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) return !DECL_ASSEMBLER_NAME_SET_P (decl); |