Hi, since we hit can of worms here, I decided to decompose the changes into minimal patches. This is first one fixing small bug introduced last July in Martin's change to add a flags to passthrough about the type preservation. This does not affect gcc-4.8
Bootstrapped/regtested x86_64-linux, will comit it shortly. * ipa-prop.c (update_jump_functions_after_inlining): When type is not preserverd by passthrough, do not propagate the type. Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 207393) +++ ipa-prop.c (working copy) @@ -2359,10 +2359,13 @@ update_jump_functions_after_inlining (st dst->type = IPA_JF_UNKNOWN; break; case IPA_JF_KNOWN_TYPE: - ipa_set_jf_known_type (dst, - ipa_get_jf_known_type_offset (src), - ipa_get_jf_known_type_base_type (src), - ipa_get_jf_known_type_base_type (src)); + if (ipa_get_jf_pass_through_type_preserved (dst)) + ipa_set_jf_known_type (dst, + ipa_get_jf_known_type_offset (src), + ipa_get_jf_known_type_base_type (src), + ipa_get_jf_known_type_base_type (src)); + else + dst->type = IPA_JF_UNKNOWN; break; case IPA_JF_CONST: ipa_set_jf_cst_copy (dst, src); Index: testsuite/g++.dg/ipa/devirt-21.C =================================================================== --- testsuite/g++.dg/ipa/devirt-21.C (revision 0) +++ testsuite/g++.dg/ipa/devirt-21.C (revision 0) @@ -0,0 +1,41 @@ +/* { dg-do run} */ +/* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fdump-ipa-cp" } */ +/* Main purpose is to verify that we do not produce wrong devirtualization to + C::m_fn1. We currently devirtualize to B::m_fn1, so check that. */ +#include <stdlib.h> +class A { +public: + unsigned length; +}; +class B {}; +class MultiTermDocs : public virtual B { +protected: + A readerTermDocs; + A subReaders; + virtual B *m_fn1(int *) {} + virtual inline ~MultiTermDocs(); + void wrap(void) + { + m_fn1(NULL); + } +}; +class C : MultiTermDocs { + B *m_fn1(int *); +}; +MultiTermDocs::~MultiTermDocs() { + wrap (); + if (&readerTermDocs) { + B *a; + for (unsigned i = 0; i < subReaders.length; i++) + (a != 0); + } +} + +B *C::m_fn1(int *) { abort (); } + +main() +{ + class C c; +} +/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */