From 233ce289250944dde071638799f9ba1a51a0a9bf Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 24 May 2015 21:38:14 +0200 Subject: [PATCH] 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 "" (odr_type_p): Simplify; add check for "" (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 "". * g++.dg/lto/pr66180_0.C: New testcase. * g++.dg/lto/pr66180_1.C: New testcase. From-SVN: r223633 --- gcc/ChangeLog | 12 +++++ gcc/cp/ChangeLog | 6 +++ gcc/cp/mangle.c | 15 +++++- gcc/ipa-devirt.c | 69 ++++++++++++++++++++-------- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/lto/pr66180_0.C | 13 ++++++ gcc/testsuite/g++.dg/lto/pr66180_1.C | 11 +++++ gcc/tree.c | 3 +- 8 files changed, 114 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lto/pr66180_0.C create mode 100644 gcc/testsuite/g++.dg/lto/pr66180_1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33f58654417..ac0301700ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-05-22 Jan Hubicka + + 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 "" + (odr_type_p): Simplify; add check for "" + (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 * ipa-utils.h (method_class_type): Remove. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 35d5f34e63f..b5168c2a2cb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-05-22 Jan Hubicka + + PR lto/66180 + * mangle.c (mangle_decl): Mangle anonymous namespace types as + "". + 2015-05-23 Nathan Sidwell PR c++/65936 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 647ec70106f..aa466cdd0fe 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 + "" 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 (""); + 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 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 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 ("", + 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 as assembler names of anonymous types. + verify that this match with type_in_anonymous_namespace_p. */ + gcc_assert (!type_with_linkage_p (t) + || strcmp ("", + 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 41a478d4dea..7e6122da271 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-05-22 Jan Hubicka + + PR lto/66180 + * g++.dg/lto/pr66180_0.C: New testcase. + * g++.dg/lto/pr66180_1.C: New testcase. + 2015-05-24 Mikael Morin 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 00000000000..c22dc284b1b --- /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 +namespace { +class A { + int i; +}; +} +class G { + std::unique_ptr foo() const; +}; +std::unique_ptr G::foo() const { return std::make_unique(); } + 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 00000000000..a4deb96f1fb --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr66180_1.C @@ -0,0 +1,11 @@ +#include +namespace { +class A { + bool a; +}; +} +class H { + std::unique_ptr bar() const; +}; +std::unique_ptr H::bar() const { return std::make_unique(); } + diff --git a/gcc/tree.c b/gcc/tree.c index caffa59d015..119bcbe1846 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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); -- 2.30.2