This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C frontend] Fix construction of TYPE_STUB_DECL


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]