mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-02 06:40:25 +08:00
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
This commit is contained in:
parent
bc0c7f396b
commit
233ce28925
@ -1,3 +1,15 @@
|
||||
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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
13
gcc/testsuite/g++.dg/lto/pr66180_0.C
Normal file
13
gcc/testsuite/g++.dg/lto/pr66180_0.C
Normal file
@ -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>(); }
|
||||
|
11
gcc/testsuite/g++.dg/lto/pr66180_1.C
Normal file
11
gcc/testsuite/g++.dg/lto/pr66180_1.C
Normal file
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user