[PATCH] Fix PR19408 -- Missing static this adjustment in a vtordisp thunk
Timur Iskhodzhanov
timurrrr at google.com
Wed Apr 16 06:53:05 PDT 2014
Hi rnk,
http://reviews.llvm.org/D3400
Files:
lib/AST/VTableBuilder.cpp
test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -2734,9 +2734,22 @@
const CXXRecordDecl *OverriderVBase =
ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase;
- if (!OverriderVBase || OverriderVBase == WhichVFPtr.getVBaseWithVPtr())
+ if (OverriderVBase == WhichVFPtr.getVBaseWithVPtr())
return;
+ if (!OverriderVBase) {
+ MethodVFTableLocation ML = VTables.getMethodVFTableLocation(Overrider.Method);
+ assert(ML.VBase && "why would we need a vtordisp if we can call the method "
+ "without a vfptr of a vbase?");
+ // We need to offset the this parameter if the offset of the vbase is
+ // different between the overrider class and the most derived class.
+ const ASTRecordLayout &OverriderRDLayout =
+ Context.getASTRecordLayout(OverriderRD);
+ TA.NonVirtual = (OverriderRDLayout.getVBaseClassOffset(ML.VBase) +
+ ML.VFPtrOffset - ThisOffset).getQuantity();
+ return;
+ }
+
// Otherwise, we need to do use the dynamic offset of the final overrider
// in order to get "this" adjustment right.
TA.Virtual.Microsoft.VBPtrOffset =
Index: test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
+++ test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
@@ -355,6 +355,40 @@
void use(A *obj) { delete obj; }
}
+namespace pr19408 {
+// In this test, the vptr used to vcall D::f() is located in the A vbase.
+// The offset of A in different in C and D, so the D vtordisp thunk should
+// adjust "this" so C::f gets the right value.
+struct A {
+ A();
+ virtual void f();
+ int a;
+};
+
+struct B : virtual A {
+ B();
+ int b;
+};
+
+struct C : B {
+ C();
+ virtual void f();
+ int c;
+};
+
+struct D : C {
+ // CHECK-LABEL: VFTable for 'pr19408::A' in 'pr19408::B' in 'pr19408::C' in 'pr19408::D' (1 entry).
+ // CHECK-NEXT: 0 | void pr19408::C::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -4 non-virtual]
+
+ // MANGLING-DAG: @"\01?f at C@pr19408@@$4PPPPPPPM at 3AEXXZ"
+ D();
+ int d;
+};
+
+D::D() {}
+}
+
namespace access {
struct A {
virtual ~A();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3400.1.patch
Type: text/x-patch
Size: 2398 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140416/1443834c/attachment.bin>
More information about the cfe-commits
mailing list