Hi, On Mon, Feb 03, 2014 at 12:52:49AM +0100, Jan Hubicka wrote: > Hi, > this patch fixes the bug in extr_type_from_vtbl_ptr_store that made it to > consider store of construction virtual table or virtual table of virtual base > as store of type's virtual table. > > In the testcase we have after early inlining: > virtual C::~C() (struct C * const this) > { > unsigned int i; > struct MultiTermDocs * _4; > struct A * _7; > unsigned int _10; > > <bb 2>: > this_2(D)->D.2980._vptr.MultiTermDocs = &MEM[(void *)&_ZTV1C + 24B]; > _4 = &this_2(D)->D.2980; > MEM[(struct MultiTermDocs *)this_2(D)]._vptr.MultiTermDocs = &MEM[(void > *)&_ZTC1C0_13MultiTermDocs + 24B]; > MultiTermDocs::wrap (_4); > > &_ZTC1C0_13MultiTermDocs is the construction vtable, while its context is > structure C and we thus assume that it is initialized to &_ZTV1C + 16B in the > rest of code. > > This leads to wrong jump function: > Jump functions of caller virtual C::~C()/29: > callsite virtual C::~C()/29 -> MultiTermDocs::~MultiTermDocs()/10 : > param 0: KNOWN TYPE: base struct C, offset 0, component struct > MultiTermDocs > param 1: CONST: &MEM[(void *)&_ZTT1C + 8B] > > This is wrong, since type of _4 at call of WRAP is really construction of C. > With the patch we get: > > Jump functions of caller virtual C::~C()/29: > callsite virtual C::~C()/29 -> void MultiTermDocs::wrap()/8 :
This jump function describes a different call than the one above, I assume the problem was that we had KNOWN_TYPE here too. > param 0: ANCESTOR: 0, offset 0, struct MultiTermDocs > > It looks bit confusing, but the ANCESTOR has no type_preserved flag, ANCESTOR jump functions certainly have type_preserved flag and as long as they are created with ipa_set_ancestor_jf it is impossible to forget to set/clear it. I have even verified we update and honor the flag during inlining. > so it is basically just PASS_THROUGH in a funny representation. Well, I have always known we produce ancestors with zero offset given exactly this kind of input but I have never seen any real need to convert them to simple pass-throughs. Anyway, the ipa-prop.c part is of course fine assuming that ipa-devirt.c parts work :-) But I'm too tired to attempt to understand it now and will probably need to read the whole file again anyway because I rememer little and am getting increasingly lost in this discussion. Thanks, Martin