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:
Jan Hubicka 2015-05-24 21:38:14 +02:00 committed by Jan Hubicka
parent bc0c7f396b
commit 233ce28925
8 changed files with 114 additions and 21 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View 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>(); }

View 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>(); }

View File

@ -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);