diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-03-20 19:19:18 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-03-20 18:19:18 +0000 |
commit | 730c436a33f0978a689c866df072ea3540ed037d (patch) | |
tree | cb30232d7f664d864a892dafa1975ac41d539179 | |
parent | 05f23918fa15005e945818fdfb9f602353193871 (diff) | |
download | gcc-730c436a33f0978a689c866df072ea3540ed037d.zip gcc-730c436a33f0978a689c866df072ea3540ed037d.tar.gz gcc-730c436a33f0978a689c866df072ea3540ed037d.tar.bz2 |
re PR lto/65475 (ICE in odr_vtable_hasher::equal (Segmentation fault))
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
-rw-r--r-- | gcc/ipa-devirt.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr65475_0.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr65475_1.C | 27 |
4 files changed, 58 insertions, 5 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index c9d153c..dd4397b 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ff3c383..8f6bde7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..273b932 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr65475_0.C @@ -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 index 0000000..642a413 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr65475_1.C @@ -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() +{ +} |