Jan Hubicka <hubi...@ucw.cz> wrote: >Hi, >while working on the devirt code, I noticed that sometimes we get >as a type of object a non-classes (like void types). This is >because we look up object's class from the OBJ_TYPE_REF_OBJECT >and this is a generic pointer that gimple passes like to change >type of. > >I tracked down few cases. For example when compiling passes.c one >gets copyrename changing > >from >void execute_ipa_summary_passes(ipa_opt_pass_d*) (struct ipa_opt_pass_d >* ipa_pass) >{ >... > struct opt_pass * pass >... > pass_12 = ipa_pass_1; >... > _20 = OBJ_TYPE_REF(_18;pass_12->3) (pass_12); > > >to > > ipa_pass_12 = ipa_pass_1 >... > _20 = OBJ_TYPE_REF(_18;ipa_pass_12->3) (ipa_pass_12); > >Ths makes us to believe that OBJ_TYPE_REF reffers to call of >method of ipa_opt_pass_d instead of opt_pass. This is wrong and >I believe it may lead to wrong code, too - the tokens have >different meanings. > >This patch changes code looking up OTR types to actually look >into OTR type (that is pointer to method) and look the class >type from type of the method's this pointer. > >Bootstrapped/regtested x86_64-linux, OK?
Ok if nobody objects. Thanks, Richard. > * tree.c (obj_type_ref_class): New function. > * tree.h (obj_type_ref_class): Declare. > * ipa-prop.c (ipa_analyze_virtual_call_uses): Use it. > > >Index: tree.c >=================================================================== >--- tree.c (revision 201764) >+++ tree.c (working copy) >@@ -11864,6 +11892,21 @@ types_same_for_odr (tree type1, tree typ > return true; > } > >+/* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */ >+ >+tree >+obj_type_ref_class (tree ref) >+{ >+ gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF); >+ ref = TREE_TYPE (ref); >+ gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE); >+ ref = TREE_TYPE (ref); >+ gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE); >+ ref = TREE_VALUE (TYPE_ARG_TYPES (ref)); >+ gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE); >+ return TREE_TYPE (ref); >+} >+ >/* Try to find a base info of BINFO that would have its field decl at >offset >OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can >be > found, return, otherwise return NULL_TREE. */ >Index: tree.h >=================================================================== >--- tree.h (revision 201764) >+++ tree.h (working copy) >@@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_loc > extern tree block_ultimate_origin (const_tree); > > extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); >+extern tree obj_type_ref_class (tree ref); > extern bool types_same_for_odr (tree type1, tree type2); > extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *, > HOST_WIDE_INT *, HOST_WIDE_INT *); >Index: ipa-prop.c >=================================================================== >--- ipa-prop.c (revision 201764) >+++ ipa-prop.c (working copy) >@@ -1903,7 +1903,7 @@ ipa_analyze_virtual_call_uses (struct cg > ii = cs->indirect_info; > ii->offset = anc_offset; > ii->otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1); >- ii->otr_type = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (target))); >+ ii->otr_type = obj_type_ref_class (target); > ii->polymorphic = 1; > } >