aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-polymorphic-call.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@gcc.gnu.org>2014-10-03 20:18:52 +0000
committerJan Hubicka <hubicka@gcc.gnu.org>2014-10-03 20:18:52 +0000
commit91e50b2d845b94111154551527ffec34d5a883ce (patch)
tree506f070d7f1610320b2329034e10834cbb211133 /gcc/ipa-polymorphic-call.c
parentbbdb509856d39eedf5bfff25f845060a965d592a (diff)
downloadgcc-91e50b2d845b94111154551527ffec34d5a883ce.zip
gcc-91e50b2d845b94111154551527ffec34d5a883ce.tar.gz
gcc-91e50b2d845b94111154551527ffec34d5a883ce.tar.bz2
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
Diffstat (limited to 'gcc/ipa-polymorphic-call.c')
-rw-r--r--gcc/ipa-polymorphic-call.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 4f0c360..f352625 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;
}