Hi in a patch I work on I store ipa_polymorphic_call_contexts in a vector and thus they do not get properly constructed, merely memset to zero. This means that I happen to be using "know nothing" contexts which have their outer_type set to NULL but the various flags are also false, unlike in the properly constructed ones.
When I pass such context to possible_polymorphic_call_targets, I get wrong complete results of size one because it sets the outer_type to otr_type but leaves the maybe_derived_type flag cleared. So I changed the function to reset the context using clear_outer_type(otr_type) instead, which I believe is the proper way of doing it. However, I had to make that method public to do so. Bootstrapped and tested on x86_64-linux. OK for trunk? Thanks, Martin 2014-11-08 Martin Jambor <mjam...@suse.cz> * cgraph.h (clear_outer_type): Make public. Fix comment. * ipa-devirt.c (possible_polymorphic_call_targets): Use clear_outer_type when resetting the context. Index: src/gcc/cgraph.h =================================================================== --- src.orig/gcc/cgraph.h 2014-11-05 17:12:51.284464567 +0100 +++ src/gcc/cgraph.h 2014-11-08 19:53:22.726610625 +0100 @@ -1334,6 +1334,10 @@ public: /* Make context non-speculative. */ void clear_speculation (); + /* Produce context specifying all derrived types of OTR_TYPE. If OTR_TYPE is + NULL, the context is set to dummy "I know nothing" setting. */ + void clear_outer_type (tree otr_type = NULL); + /* Walk container types and modify context to point to actual class containing OTR_TYPE (if non-NULL) as base class. Return true if resulting context is valid. @@ -1374,7 +1378,6 @@ private: bool combine_speculation_with (tree, HOST_WIDE_INT, bool, tree); void set_by_decl (tree, HOST_WIDE_INT); bool set_by_invariant (tree, tree, HOST_WIDE_INT); - void clear_outer_type (tree otr_type = NULL); bool speculation_consistent_p (tree, HOST_WIDE_INT, bool, tree); void make_speculative (tree otr_type = NULL); }; @@ -2724,9 +2727,8 @@ ipa_polymorphic_call_context::clear_spec speculative_maybe_derived_type = false; } -/* Produce context specifying all derrived types of OTR_TYPE. - If OTR_TYPE is NULL or type of the OBJ_TYPE_REF, the context is set - to dummy "I know nothing" setting. */ +/* Produce context specifying all derrived types of OTR_TYPE. If OTR_TYPE is + NULL, the context is set to dummy "I know nothing" setting. */ inline void ipa_polymorphic_call_context::clear_outer_type (tree otr_type) Index: src/gcc/ipa-devirt.c =================================================================== --- src.orig/gcc/ipa-devirt.c 2014-11-03 20:17:30.200011833 +0100 +++ src/gcc/ipa-devirt.c 2014-11-08 19:48:47.882600150 +0100 @@ -2281,10 +2281,7 @@ possible_polymorphic_call_targets (tree /* Without outer type, we have no use for offset. Just do the basic search from innter type */ if (!context.outer_type) - { - context.outer_type = otr_type; - context.offset = 0; - } + context.clear_outer_type (otr_type); /* We need to update our hiearchy if the type does not exist. */ outer_type = get_odr_type (context.outer_type, true); /* If the type is complete, there are no derivations. */