re PR lto/66180 (many -Wodr false positives when building LLVM with -flto)
authorJan Hubicka <hubicka@ucw.cz>
Sun, 24 May 2015 19:38:14 +0000 (21:38 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 24 May 2015 19:38:14 +0000 (19:38 +0000)
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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/pr66180_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr66180_1.C [new file with mode: 0644]
gcc/tree.c

index 33f58654417699399e2970bacfbd4befbae2f060..ac0301700ad03f9ec28f2e297320b1ac23ad8e55 100644 (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.
index 35d5f34e63f7c63232b650bdd7e4711c056846a1..b5168c2a2cb98a171b3c8063108a78c88acd146b 100644 (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
index 647ec70106fdbba6ebece91eb28f4fdf419332a6..aa466cdd0fee34c0d3ccde246f64c002940db7b7 100644 (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
index 77ecd0d2d8311b47f958e71530efce38036c6fea..29438740db39c65992af9e07dec6a0cfd9eeca8e 100644 (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;
     }
 
index 41a478d4dea842e6ede68a31a00e7c5d29c3eef0..7e6122da27119a3a3fb2a3a772cf6b74bb96bed9 100644 (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
diff --git a/gcc/testsuite/g++.dg/lto/pr66180_0.C b/gcc/testsuite/g++.dg/lto/pr66180_0.C
new file mode 100644 (file)
index 0000000..c22dc28
--- /dev/null
@@ -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 (file)
index 0000000..a4deb96
--- /dev/null
@@ -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 caffa59d015a53127d5155ef659d6ab054cb0b6f..119bcbe18464673b5f7ed850c8217b20fe98b2ad 100644 (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);