Resolution of B-2 not reflected in B-6 (aka covariant returns)

Jim Dehnert dehnert at baalbek.engr.sgi.com
Wed Mar 8 23:54:11 UTC 2000


> Date: Tue, 7 Mar 2000 23:16:37 +0100
> From: Martin von Loewis <loewis at informatik.hu-berlin.de>
> 
> I just tried to understand our scheme for covariant returns, and found
> I couldn't. All I found was:
> 
> - there are different vtable entries for each different return type.
> - at the end of issue B-2, it is explained that the exact definition
>   is found in issue B-6.
> - in issue B-6, it is explained that the resolution to that issue is
>   found in the ABI layout document
> - in the ABI layout document, there is no mentioning of covariant
>   returns.

You seem to be correct.  Let me try to explain my understanding of the
situation and an appropriate rule derived from that, and then those of
you more knowledgeable can clarify.

> If desired, I can try to produce a draft.

That would be good, if you have a better scheme than below.

First, a simple example:

	class T {
	  virtual void f();
	};
	class A {
	  virtual A* foo (void);
	};
	class B: public T, public A {
	  virtual A* foo (void);
	};
	class C: public B {
	  virtual C* foo (void);
	};
	A* a = new A;
	B* b = new B;	A* a_in_b = b;
	C* c = new C;	B* b_in_c = c;

Now, our layout rules, ignoring the covariant returns, provide:

  1. Vtable A:  entry for A::foo non-adjusting (a->foo)
  2. Vtable B:  entry for B::foo non-adjusting (b->foo)
  3. Vtable A-in-B (not primary):  entry for B::foo adjusting (a_in_b->foo)
  4. Vtable C:  entry for C::foo non-adjusting (c->foo)
  5. Vtable B-in-C (primary):  entry for C::foo non-adjusting (b_in_c->foo)
  6. Vtable A-in-C (not primary):  entry for C::foo adjusting (a_in_c->foo)

Now, if we assume that all of the adjusting entrypoints also adjust the
return pointer if necessary (it's not always, e.g. case (3)),
everything works fine EXCEPT case (5).  In that case, the B-in-C vtable
is primary, so the vtable C and vtable B-in-C entries for foo are the
same entry.  But the C entry needs no result adjustment, and the B
entry does (to an A*).

I think this can be dealt with by the following rule:

  The adjusting entrypoints referenced by vtable entries in secondary
  vtables must adjust both the this pointer and the covariant return
  pointer (if necessary).  If a derived class and its primary base
  share a vtable, and the derived class overrides a virtual function in
  the primary base's primary vtable with a different return type, then
  the shared vtable entry adjusts the return type to that required by
  the base class, and a second entry is allocated in the derived type's
  vtable (according to the position rules for any vfunc added by the
  derived class) for the overriding function, which adjusts neither
  this nor the return type.

Note that this rule does not provide what I originally assumed was
meant by "multiple entries for covariant returns," as it makes use of
the multiple entries already present in secondary vtables when it can.

Am I missing anything?  Is this clear?  Other comments?

Jim

-	    Jim Dehnert		dehnert at sgi.com
				(650)933-4272




More information about the cxx-abi-dev mailing list