This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][C++] Fix PR38334, TBAA issues with vtbl loads


On Tue, 2 Dec 2008, Mark Mitchell wrote:

> Richard Guenther wrote:
> 
> >> Why not?  I thought a C++ class with a virtual function would have a
> >> member in it that corresponds to the virtual table pointer (possibly
> >> inside nested structures).
> > 
> > I think we do not need to know the class in this case dealing with
> > pointer-to-member functions.
> 
> Oh, I see.  You're right; we don't know the static type of the class we
> reach by adding delta to the "this" pointer.
> 
> However, that means that "this + delta" shouldn't be considered based on
> "this".  It's not like an array access; it's an access outside the
> bounds of "*this" to some object fundamentally unrelated to "*this".
> Can we either cast the type of that expression to vtbl**, or can we mark
> this + delta as being of an all-aliasing type?

This is what the patch does - it makes this + delta an all-aliasing type
(a ref-all pointer to the vtbl pointer).  So dereferencing that is fine.

> The point is that it's the "this + delta" operation that's weird from a
> typing point of view; the subsequent dereference of that pointer is normal.

I guess for the case in question the dereference is not normal - we have
two code-paths (of which one is hopefully never executed as it contains
a clearly bogus access):

  struct Container t;

<bb 2>:
  itemfunptr$__delta_1 = 0;
  arg1.__delta = 0;
  arg1.__pfn = fred;
  D.1853_6 = (int) itemfun;
  D.1854_7 = D.1853_6 & 1;
  if (D.1854_7 != 0)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 3>:
  D.1857_10 = (int (*__vtbl_ptr_type) (void) * *) &t;
  D.1858_11 = *D.1857_10;
  D.1859_12 = itemfun + -1;
  D.1860_13 = (unsigned int) D.1859_12;
  D.1861_14 = D.1858_11 + D.1860_13;
  D.1862_15 = *D.1861_14;
  itemfunptr$__pfn_16 = (Container:: *) D.1862_15;

<bb 4>:
  # itemfunptr$__pfn_19 = PHI <itemfun(2), itemfunptr$__pfn_16(3)>
  itemfunptr$__pfn_19 (&t, arg1, 1);
  return 0;

optimization figured out that the memfun delta is zero, so if
D.1853_6 & 1 is true we load the vtbl pointer from the start of
the object in question (where there isn't such).  If the condition
is false all is ok.  So here you could argue it is enough to silence
the warning (even removing the bogus access would be fine if it
is never executed).  I'm just not sure if that is really the case,
so I tried to play safe with making the load of the vtbl pointer
alias everything.

(inlining and scalarization/ccp is necessary to arrive at the above
situation, another interesting situation to investigate would be
to have the initialization code of the vtbl pointer inlined into
the same function as an access - but no idea how to provoke this).

Thanks,
Richard.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]