Hi,
this patch fixes ICE in where ODR violation merge non-polymorphic and
polymorphic type.

I will keep the PR open as I would like to improve the ODR violation warning

Bootstrapped/regtested x86_64-linux, will commit it tomorrow.

Honza

        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.
Index: testsuite/g++.dg/lto/pr65475_0.C
===================================================================
--- testsuite/g++.dg/lto/pr65475_0.C    (revision 0)
+++ testsuite/g++.dg/lto/pr65475_0.C    (revision 0)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -r -nostdlib" } */
+namespace std {
+class ios_base {
+  struct A {};
+  class __attribute((__abi_tag__("cxx11"))) failure : A {};
+} a;
+}
+
Index: testsuite/g++.dg/lto/pr65475_1.C
===================================================================
--- testsuite/g++.dg/lto/pr65475_1.C    (revision 0)
+++ testsuite/g++.dg/lto/pr65475_1.C    (revision 0)
@@ -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()
+{
+}
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c        (revision 221528)
+++ ipa-devirt.c        (working copy)
@@ -1412,9 +1412,18 @@ add_type_duplicate (odr_type val, tree t
   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);

Reply via email to