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