Problem with vcall offsets

Mark Mitchell mark at codesourcery.com
Tue Jul 2 18:06:11 UTC 2002


I believe that there is a major defect in the ABI specification with
respect to virtual tables:

In particular, consider:

  struct V {
    virtual void v();
  };

  struct P : virtual public V { 
    virtual void p();
  };

  struct A : virtual public P {
    virtual void a();
  };

Consider the case where A is being used a virtual base.

V is primary in P and P is primary in A.

Section 2.5.3 says:

   If virtual base A has a primary virtual base class P sharing its
   virtual table, P's vbase and vcall offsets come first in the
   primary virtual table, in the same order they would appear if P
   itself were the virtual base, and those from A that do not replicate
   those from P precede them.

In other words, the vtable for A, when used as a virtual base is:

   A's vcall offset for A::a
   A's vbase offset to P
   P's vcall offset for P::p
   P's vbase offset to V
   V's vcall offset for V::v
   Offset-to-top
   Typeinfo 
   Entry for V::v
   Entry for P::p
   Entry for A::a

This cannot possibly be right.  If you want to be able to generate
code to cast from an A* to a P*, then the index of A's vbase offset
for P must be constant; it cannot depend on whether or not A itself is
a virtual base in something else.  That implies that the vbase and
vcall offsets cannot be interleaved; instead, the vbase offsets must
always come nearest the address point.

On the other hand, if the position of the vcall offsets are different
when A is used as a virtual base than when P is used as a virtual
base, then thunks generated for P::p are not going to work any more.

I think that we need to always emit vcall offsets, even for bases that
are not virtual.

Thoughts?

--
Mark Mitchell                   mark at codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com




More information about the cxx-abi-dev mailing list