From b270b096a14b869e59e10ca879b5cffa65ea3fd5 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 10 Jan 2014 22:34:37 +0100 Subject: [PATCH] re PR middle-end/58585 (ICE in ipa with virtual inheritance) PR ipa/58585 * ipa-devirt.c (build_type_inheritance_graph): Also add types of vtables into the type inheritance graph. * g++.dg/torture/pr58585.C: New testcase. From-SVN: r206543 --- gcc/ChangeLog | 6 +++++ gcc/ipa-devirt.c | 33 +++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/torture/pr58585.C | 20 ++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr58585.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 89f60a2ea1f..54d62608a94 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-01-10 Jan Hubicka + + PR ipa/58585 + * ipa-devirt.c (build_type_inheritance_graph): Also add types of vtables + into the type inheritance graph. + 2014-01-10 Jakub Jelinek PR rtl-optimization/59754 diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index b0bedacd609..fb03dd2618d 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -542,7 +542,7 @@ method_class_type (tree t) void build_type_inheritance_graph (void) { - struct cgraph_node *n; + struct symtab_node *n; FILE *inheritance_dump_file; int flags; @@ -554,10 +554,37 @@ build_type_inheritance_graph (void) /* We reconstruct the graph starting of types of all methods seen in the the unit. */ - FOR_EACH_FUNCTION (n) - if (DECL_VIRTUAL_P (n->decl) + FOR_EACH_SYMBOL (n) + if (is_a (n) + && DECL_VIRTUAL_P (n->decl) && symtab_real_symbol_p (n)) get_odr_type (method_class_type (TREE_TYPE (n->decl)), true); + + /* Look also for virtual tables of types that do not define any methods. + + We need it in a case where class B has virtual base of class A + re-defining its virtual method and there is class C with no virtual + methods with B as virtual base. + + Here we output B's virtual method in two variant - for non-virtual + and virtual inheritance. B's virtual table has non-virtual version, + while C's has virtual. + + For this reason we need to know about C in order to include both + variants of B. More correctly, record_target_from_binfo should + add both variants of the method when walking B, but we have no + link in between them. + + We rely on fact that either the method is exported and thus we + assume it is called externally or C is in anonymous namespace and + thus we will see the vtable. */ + + else if (is_a (n) + && DECL_VIRTUAL_P (n->decl) + && TREE_CODE (DECL_CONTEXT (n->decl)) == RECORD_TYPE + && TYPE_BINFO (DECL_CONTEXT (n->decl)) + && polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (n->decl)))) + get_odr_type (DECL_CONTEXT (n->decl), true); if (inheritance_dump_file) { dump_type_inheritance_graph (inheritance_dump_file); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8ccfe652a8e..4373d0ffcc2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-10 Jan Hubicka + + PR ipa/58585 + * g++.dg/torture/pr58585.C: New testcase. + 2014-01-10 Hans-Peter Nilsson * gcc.dg/pr46309.c: Disable for cris*-*-*. diff --git a/gcc/testsuite/g++.dg/torture/pr58585.C b/gcc/testsuite/g++.dg/torture/pr58585.C new file mode 100644 index 00000000000..69fcf04ddc1 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr58585.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-fpic" { target fpic } } +struct A +{ + virtual void foo() {} + void bar(); +}; +void A::bar() { foo(); } + +struct B : virtual A +{ + virtual void foo() {} + char c; +}; + +struct C : virtual B +{ + C(); +}; +C::C() { bar(); } -- 2.30.2