aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-05-24 21:38:14 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-05-24 19:38:14 +0000
commit233ce289250944dde071638799f9ba1a51a0a9bf (patch)
treefcafa16d16e0f29657b3cc4999c520546d0e89f1 /gcc
parentbc0c7f396b0c9648365aee462e25107db00227e8 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/mangle.c15
-rw-r--r--gcc/ipa-devirt.c69
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/lto/pr66180_0.C13
-rw-r--r--gcc/testsuite/g++.dg/lto/pr66180_1.C11
-rw-r--r--gcc/tree.c3
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>(); }
+
diff --git a/gcc/tree.c b/gcc/tree.c
index caffa59..119bcbe 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);