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