From c7e1befad2b375b2245dca11329df92b600ef3ed Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 28 Jun 2014 20:26:12 +0200 Subject: [PATCH] ipa-devirt.c (set_type_binfo): New function. * ipa-devirt.c (set_type_binfo): New function. (add_type_duplicate): Use it. (get_odr_type): Sanity check that binfos points to main variants. (get_class_context): Be sure the context's outer_type is main variant. (contains_type_p): Walk main variant. (get_polymorphic_call_info_for_decl): Set outer_type to be main variant. (get_polymorphic_call_info): Likewise. (possible_polymorphic_call_targets): Sanity check that we operate on main variant. From-SVN: r212107 --- gcc/ChangeLog | 12 ++++++++++++ gcc/ipa-devirt.c | 46 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 245c20d66fb..f5d9983d1d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-06-28 Jan Hubicka + + * ipa-devirt.c (set_type_binfo): New function. + (add_type_duplicate): Use it. + (get_odr_type): Sanity check that binfos points to main variants. + (get_class_context): Be sure the context's outer_type is main variant. + (contains_type_p): Walk main variant. + (get_polymorphic_call_info_for_decl): Set outer_type to be main variant. + (get_polymorphic_call_info): Likewise. + (possible_polymorphic_call_targets): Sanity check that we operate on main + variant. + 2014-06-28 Jan Hubicka * stor-layout.c (finish_builtin_struct): Copy fields into diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index d6b85bf3415..d893ff5bec4 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -334,6 +334,17 @@ static odr_hash_type *odr_hash; static GTY(()) vec *odr_types_ptr; #define odr_types (*odr_types_ptr) +/* Set TYPE_BINFO of TYPE and its variants to BINFO. */ +void +set_type_binfo (tree type, tree binfo) +{ + for (; type; type = TYPE_NEXT_VARIANT (type)) + if (COMPLETE_TYPE_P (type)) + TYPE_BINFO (type) = binfo; + else + gcc_assert (!TYPE_BINFO (type)); +} + /* TYPE is equivalent to VAL by ODR, but its tree representation differs from VAL->type. This may happen in LTO where tree merging did not merge all variants of the same type. It may or may not mean the ODR violation. @@ -446,16 +457,17 @@ add_type_duplicate (odr_type val, tree type) { unsigned int i; - TYPE_BINFO (val->type) = TYPE_BINFO (type); + set_type_binfo (val->type, TYPE_BINFO (type)); for (i = 0; i < val->types->length (); i++) { if (TYPE_BINFO ((*val->types)[i]) == master_binfo) - TYPE_BINFO ((*val->types)[i]) = TYPE_BINFO (type); + set_type_binfo ((*val->types)[i], TYPE_BINFO (type)); } + BINFO_TYPE (TYPE_BINFO (type)) = val->type; } else - TYPE_BINFO (type) = master_binfo; + set_type_binfo (type, master_binfo); } } } @@ -495,6 +507,7 @@ get_odr_type (tree type, bool insert) val = ggc_cleared_alloc (); val->type = type; + gcc_assert (BINFO_TYPE (TYPE_BINFO (val->type)) = type); val->bases = vNULL; val->derived_types = vNULL; val->anonymous_namespace = type_in_anonymous_namespace_p (type); @@ -1102,7 +1115,7 @@ get_class_context (ipa_polymorphic_call_context *context, if (!fld) goto give_up; - type = TREE_TYPE (fld); + type = TYPE_MAIN_VARIANT (TREE_TYPE (fld)); offset -= pos; /* DECL_ARTIFICIAL represents a basetype. */ if (!DECL_ARTIFICIAL (fld)) @@ -1116,7 +1129,7 @@ get_class_context (ipa_polymorphic_call_context *context, } else if (TREE_CODE (type) == ARRAY_TYPE) { - tree subtype = TREE_TYPE (type); + tree subtype = TYPE_MAIN_VARIANT (TREE_TYPE (type)); /* Give up if we don't know array size. */ if (!tree_fits_shwi_p (TYPE_SIZE (subtype)) @@ -1159,7 +1172,8 @@ static bool contains_type_p (tree outer_type, HOST_WIDE_INT offset, tree otr_type) { - ipa_polymorphic_call_context context = {offset, outer_type, + ipa_polymorphic_call_context context = {offset, + TYPE_MAIN_VARIANT (outer_type), false, true}; return get_class_context (&context, otr_type); } @@ -1272,7 +1286,7 @@ get_polymorphic_call_info_for_decl (ipa_polymorphic_call_context *context, { gcc_assert (DECL_P (base)); - context->outer_type = TREE_TYPE (base); + context->outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base)); context->offset = offset; /* Make very conservative assumption that all objects may be in construction. @@ -1329,7 +1343,7 @@ get_polymorphic_call_info (tree fndecl, *otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref)); /* Set up basic info in case we find nothing interesting in the analysis. */ - context->outer_type = *otr_type; + context->outer_type = TYPE_MAIN_VARIANT (*otr_type); context->offset = 0; base_pointer = OBJ_TYPE_REF_OBJECT (ref); context->maybe_derived_type = true; @@ -1415,7 +1429,8 @@ get_polymorphic_call_info (tree fndecl, if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE && SSA_NAME_VAR (base_pointer) == DECL_ARGUMENTS (fndecl)) { - context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer)); + context->outer_type + = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer))); gcc_assert (TREE_CODE (context->outer_type) == RECORD_TYPE); /* Dynamic casting has possibly upcasted the type @@ -1450,7 +1465,8 @@ get_polymorphic_call_info (tree fndecl, object. */ if (DECL_BY_REFERENCE (SSA_NAME_VAR (base_pointer))) { - context->outer_type = TREE_TYPE (TREE_TYPE (base_pointer)); + context->outer_type + = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer))); gcc_assert (!POINTER_TYPE_P (context->outer_type)); /* Only type inconsistent programs can have otr_type that is not part of outer type. */ @@ -1599,6 +1615,8 @@ possible_polymorphic_call_targets (tree otr_type, bool can_refer; bool skipped = false; + otr_type = TYPE_MAIN_VARIANT (otr_type); + /* If ODR is not initialized, return empty incomplete list. */ if (!odr_hash) { @@ -1625,6 +1643,10 @@ possible_polymorphic_call_targets (tree otr_type, type = get_odr_type (otr_type, true); + /* Recording type variants would wast results cache. */ + gcc_assert (!context.outer_type + || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type); + /* Lookup the outer class type we want to walk. */ if (context.outer_type && !get_class_context (&context, otr_type)) @@ -1638,6 +1660,10 @@ possible_polymorphic_call_targets (tree otr_type, return nodes; } + /* Check that get_class_context kept the main variant. */ + gcc_assert (!context.outer_type + || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type); + /* We canonicalize our query, so we do not need extra hashtable entries. */ /* Without outer type, we have no use for offset. Just do the