aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-03-20 19:19:18 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-03-20 18:19:18 +0000
commit730c436a33f0978a689c866df072ea3540ed037d (patch)
treecb30232d7f664d864a892dafa1975ac41d539179
parent05f23918fa15005e945818fdfb9f602353193871 (diff)
downloadgcc-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.c20
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/lto/pr65475_0.C10
-rw-r--r--gcc/testsuite/g++.dg/lto/pr65475_1.C27
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()
+{
+}