From 91e50b2d845b94111154551527ffec34d5a883ce Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 3 Oct 2014 20:18:52 +0000 Subject: [PATCH] ipa-polymorphic-call.c (decl_maybe_in_construction_p): Be ready for BASE and OUTER_TYPE being NULL. * ipa-polymorphic-call.c (decl_maybe_in_construction_p): Be ready for BASE and OUTER_TYPE being NULL. (ipa_polymorphic_call_context::possible_dynamic_type_change): Add in_poly_cdtor parameter. From-SVN: r215876 --- gcc/ipa-polymorphic-call.c | 49 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 4f0c360b8cf..f352625fc78 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -475,6 +475,11 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset, (not dynamically allocated) and we want to disprove the fact that it may be in construction at invocation of CALL. + BASE represents memory location where instance is stored. + If BASE is NULL, it is assumed to be global memory. + OUTER_TYPE is known type of the instance or NULL if not + known. + For the variable to be in construction we actually need to be in constructor of corresponding global variable or the inline stack of CALL must contain the constructor. @@ -486,8 +491,9 @@ bool decl_maybe_in_construction_p (tree base, tree outer_type, gimple call, tree function) { - outer_type = TYPE_MAIN_VARIANT (outer_type); - gcc_assert (DECL_P (base)); + if (outer_type) + outer_type = TYPE_MAIN_VARIANT (outer_type); + gcc_assert (!base || DECL_P (base)); /* After inlining the code unification optimizations may invalidate inline stacks. Also we need to give up on global variables after @@ -498,7 +504,7 @@ decl_maybe_in_construction_p (tree base, tree outer_type, /* Pure functions can not do any changes on the dynamic type; that require writting to memory. */ - if (!auto_var_in_fn_p (base, function) + if ((!base || !auto_var_in_fn_p (base, function)) && flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST)) return false; @@ -517,7 +523,7 @@ decl_maybe_in_construction_p (tree base, tree outer_type, argument (pointer to the instance). */ fn = DECL_ABSTRACT_ORIGIN (fn); if (!fn - || !is_global_var (base) + || (base && !is_global_var (base)) || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn))) @@ -526,17 +532,20 @@ decl_maybe_in_construction_p (tree base, tree outer_type, if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST)) continue; - /* FIXME: this can go away once we have ODR types equivalency on - LTO level. */ - if (in_lto_p && !polymorphic_type_binfo_p (TYPE_BINFO (outer_type))) - return true; tree type = TYPE_MAIN_VARIANT (method_class_type (TREE_TYPE (fn))); - if (types_same_for_odr (type, outer_type)) + + if (!outer_type || !types_odr_comparable (type, outer_type)) + { + if (TREE_CODE (type) == RECORD_TYPE + && TYPE_BINFO (type) + && polymorphic_type_binfo_p (TYPE_BINFO (type))) + return true; + } + else if (types_same_for_odr (type, outer_type)) return true; } - if (TREE_CODE (base) == VAR_DECL - && is_global_var (base)) + if (!base || (TREE_CODE (base) == VAR_DECL && is_global_var (base))) { if (TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE || (!DECL_CXX_CONSTRUCTOR_P (function) @@ -553,12 +562,15 @@ decl_maybe_in_construction_p (tree base, tree outer_type, && !DECL_CXX_DESTRUCTOR_P (function))) return false; } - /* FIXME: this can go away once we have ODR types equivalency on - LTO level. */ - if (in_lto_p && !polymorphic_type_binfo_p (TYPE_BINFO (outer_type))) - return true; tree type = TYPE_MAIN_VARIANT (method_class_type (TREE_TYPE (function))); - if (types_same_for_odr (type, outer_type)) + if (!outer_type || !types_odr_comparable (type, outer_type)) + { + if (TREE_CODE (type) == RECORD_TYPE + && TYPE_BINFO (type) + && polymorphic_type_binfo_p (TYPE_BINFO (type))) + return true; + } + else if (types_same_for_odr (type, outer_type)) return true; } return false; @@ -2009,10 +2021,11 @@ ipa_polymorphic_call_context::make_speculative (tree otr_type) type change is not happening. */ void -ipa_polymorphic_call_context::possible_dynamic_type_change (tree otr_type) +ipa_polymorphic_call_context::possible_dynamic_type_change (bool in_poly_cdtor, + tree otr_type) { if (dynamic) make_speculative (otr_type); - else + else if (in_poly_cdtor) maybe_in_construction = true; } -- 2.30.2