зеркало из https://github.com/microsoft/clang-1.git
When re-using a vtable slot for the nearest overridden method, just because
there's no return adjustment from the overridden to the overrider doesn't mean there isn't a return adjustment from the overrider to the final overrider. This matters if we're emitting a virtual this-adjustment thunk because the overrider virtually inherits from the class providing the nearest overridden method. Do the appropriate return adjustment in this case. Fixes PR7611. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118466 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
43328e9162
Коммит
4e3b17c9ce
|
@ -1664,9 +1664,18 @@ VTableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,
|
||||||
|
|
||||||
if (ThisAdjustment.VCallOffsetOffset &&
|
if (ThisAdjustment.VCallOffsetOffset &&
|
||||||
Overrider.Method->getParent() == MostDerivedClass) {
|
Overrider.Method->getParent() == MostDerivedClass) {
|
||||||
|
|
||||||
|
// There's no return adjustment from OverriddenMD and MD,
|
||||||
|
// but that doesn't mean there isn't one between MD and
|
||||||
|
// the final overrider.
|
||||||
|
BaseOffset ReturnAdjustmentOffset =
|
||||||
|
ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD);
|
||||||
|
ReturnAdjustment ReturnAdjustment =
|
||||||
|
ComputeReturnAdjustment(ReturnAdjustmentOffset);
|
||||||
|
|
||||||
// This is a virtual thunk for the most derived class, add it.
|
// This is a virtual thunk for the most derived class, add it.
|
||||||
AddThunk(Overrider.Method,
|
AddThunk(Overrider.Method,
|
||||||
ThunkInfo(ThisAdjustment, ReturnAdjustment()));
|
ThunkInfo(ThisAdjustment, ReturnAdjustment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,25 @@ namespace Test10 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR7611
|
||||||
|
namespace Test11 {
|
||||||
|
struct A { virtual A* f(); };
|
||||||
|
struct B : virtual A { virtual A* f(); };
|
||||||
|
struct C : B { virtual C* f(); };
|
||||||
|
C* C::f() { return 0; }
|
||||||
|
|
||||||
|
// The this-adjustment and return-adjustment thunk required when
|
||||||
|
// C::f appears in a vtable where A is at a nonzero offset from C.
|
||||||
|
// CHECK: define {{.*}} @_ZTcv0_n24_v0_n32_N6Test111C1fEv(
|
||||||
|
|
||||||
|
// C::f itself.
|
||||||
|
// CHECK: define {{.*}} @_ZN6Test111C1fEv(
|
||||||
|
|
||||||
|
// The return-adjustment thunk required when C::f appears in a vtable
|
||||||
|
// where A is at a zero offset from C.
|
||||||
|
// CHECK: define {{.*}} @_ZTch0_v0_n32_N6Test111C1fEv(
|
||||||
|
}
|
||||||
|
|
||||||
/**** The following has to go at the end of the file ****/
|
/**** The following has to go at the end of the file ****/
|
||||||
|
|
||||||
// This is from Test5:
|
// This is from Test5:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче