This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C frontend] Fix construction of TYPE_STUB_DECL
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org, joseph at codesourcery dot com, rth at redhat dot com
- Date: Sun, 24 May 2015 09:02:49 +0200
- Subject: Re: [C frontend] Fix construction of TYPE_STUB_DECL
- Authentication-results: sourceware.org; auth=none
- References: <20150510173354 dot GB80167 at kam dot mff dot cuni dot cz> <55511E76 dot 4030503 at redhat dot com> <20150511215215 dot GC35526 at kam dot mff dot cuni dot cz> <20150513165634 dot GA85184 at kam dot mff dot cuni dot cz> <20150521203214 dot GA14223 at kam dot mff dot cuni dot cz> <555E4D00 dot 5050703 at redhat dot com>
Hi,
this patch implements the idea. It uses "<anon>" for anonymous namespace
types and updates ipa-devirt to rely on it (and also sanity check that).
The patch has bootstrapped/regtested powerpc64le-linux, will commit it
tomorrow if there are no complains to unbreak the Ada LTO bootstrap.
Honza
PR lto/66180
* mangle.c (mangle_decl): Mangle anonymous namespace types as "<anon>"
* 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.
* g++.dg/lto/pr66180_0.C: New testcase.
* g++.dg/lto/pr66180_1.C: New testcase.
Index: cp/mangle.c
===================================================================
--- cp/mangle.c (revision 223628)
+++ cp/mangle.c (working copy)
@@ -3511,7 +3511,20 @@
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
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 223629)
+++ ipa-devirt.c (working copy)
@@ -252,9 +252,15 @@
{
/* 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 && !DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)))
+ return false;
+
return (RECORD_OR_UNION_TYPE_P (t)
|| TREE_CODE (t) == ENUMERAL_TYPE);
}
@@ -269,18 +275,14 @@
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 +294,25 @@
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))));
+ 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 +787,7 @@
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;
}
Index: testsuite/g++.dg/lto/pr66180_0.C
===================================================================
--- testsuite/g++.dg/lto/pr66180_0.C (revision 0)
+++ testsuite/g++.dg/lto/pr66180_0.C (working copy)
@@ -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>(); }
+
Index: testsuite/g++.dg/lto/pr66180_1.C
===================================================================
--- testsuite/g++.dg/lto/pr66180_1.C (revision 0)
+++ testsuite/g++.dg/lto/pr66180_1.C (working copy)
@@ -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>(); }
+
Index: tree.c
===================================================================
--- tree.c (revision 223629)
+++ tree.c (working copy)
@@ -5182,8 +5182,7 @@
&& 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);