re PR lto/65475 (ICE in odr_vtable_hasher::equal (Segmentation fault))
authorJan Hubicka <hubicka@ucw.cz>
Fri, 20 Mar 2015 18:19:18 +0000 (19:19 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 20 Mar 2015 18:19:18 +0000 (18:19 +0000)
PR ipa/65475
* ipa-devirt.c (add_type_duplicate): Prevail polymorphic type over
non-polymorphic
* g++.dg/lto/pr65475_0.C: New testcase.
* g++.dg/lto/pr65475_1.C: New testcase.

From-SVN: r221542

gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/pr65475_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr65475_1.C [new file with mode: 0644]

index c9d153c1b99c2e3456b64fb7125e05e9d976119d..dd4397bbf28f9bd1226ab2ce497c4cbd72cbb294 100644 (file)
@@ -1412,9 +1412,18 @@ add_type_duplicate (odr_type val, tree type)
   if (!val->types_set)
     val->types_set = new hash_set<tree>;
 
+  /* Chose polymorphic type as leader (this happens only in case of ODR
+     violations.  */
+  if ((TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (type)
+       && polymorphic_type_binfo_p (TYPE_BINFO (type)))
+      && (TREE_CODE (val->type) != RECORD_TYPE || !TYPE_BINFO (val->type)
+          || !polymorphic_type_binfo_p (TYPE_BINFO (val->type))))
+    {
+      prevail = true;
+      build_bases = true;
+    }
   /* Always prefer complete type to be the leader.  */
-
-  if (!COMPLETE_TYPE_P (val->type) && COMPLETE_TYPE_P (type))
+  else if (!COMPLETE_TYPE_P (val->type) && COMPLETE_TYPE_P (type))
     {
       prevail = true;
       build_bases = TYPE_BINFO (type);
@@ -1563,7 +1572,8 @@ add_type_duplicate (odr_type val, tree type)
                   Be sure this does not happen.  */
                gcc_assert (TYPE_BINFO (type2)
                            || !polymorphic_type_binfo_p (TYPE_BINFO (type1))
-                           || build_bases);
+                           || build_bases
+                           || val->odr_violated);
                break;
              }
            /* One base is polymorphic and the other not.
@@ -1865,9 +1875,9 @@ dump_odr_type (FILE *f, odr_type t, int indent=0)
   fprintf (f, "%s\n", t->all_derivations_known ? " (derivations known)":"");
   if (TYPE_NAME (t->type))
     {
-      fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
+      /*fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
               DECL_SOURCE_FILE (TYPE_NAME (t->type)),
-              DECL_SOURCE_LINE (TYPE_NAME (t->type)));
+              DECL_SOURCE_LINE (TYPE_NAME (t->type)));*/
       if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t->type)))
         fprintf (f, "%*s mangled name: %s\n", indent * 2, "",
                 IDENTIFIER_POINTER
index ff3c3836c0e693c2f04e2627a6b4b3e298aab079..8f6bde77004d5feeb7f0d0e2955222baf5814bfb 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-20  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/65475
+       * g++.dg/lto/pr65475_0.C: New testcase.
+       * g++.dg/lto/pr65475_1.C: New testcase.
+
 2015-03-20  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/64366
diff --git a/gcc/testsuite/g++.dg/lto/pr65475_0.C b/gcc/testsuite/g++.dg/lto/pr65475_0.C
new file mode 100644 (file)
index 0000000..273b932
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-lto-do link } */
+/* { dg-options "-O2  -Wno-odr" } */
+/* { dg-extra-ld-options { -O2 -Wno-odr -r -nostdlib } } */
+namespace std {
+class ios_base {
+  struct A {};
+  class __attribute((__abi_tag__("cxx11"))) failure : A {};
+} a;
+}
+
diff --git a/gcc/testsuite/g++.dg/lto/pr65475_1.C b/gcc/testsuite/g++.dg/lto/pr65475_1.C
new file mode 100644 (file)
index 0000000..642a413
--- /dev/null
@@ -0,0 +1,27 @@
+namespace std {
+template <typename, typename = int> class Trans_NS___cxx11_basic_ostringstream;
+class ios_base {
+  class __attribute((__abi_tag__("cxx11"))) failure {
+    virtual char m_fn2();
+  };
+};
+class B : virtual ios_base {};
+template <typename, typename> class Trans_NS___cxx11_basic_ostringstream : B {
+public:
+  void m_fn1();
+};
+}
+
+class A {
+public:
+  A(int) {
+    std::Trans_NS___cxx11_basic_ostringstream<wchar_t> a;
+    a.m_fn1();
+  }
+};
+int b;
+void fn1() { (A(b)); }
+int
+main()
+{
+}