]> granicus.if.org Git - clang/commitdiff
MS ABI: Mangle virtual member pointer thunks with the correct CC
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 14 Mar 2015 06:34:41 +0000 (06:34 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 14 Mar 2015 06:34:41 +0000 (06:34 +0000)
Virtual member pointers are implemented using a thunk.  We assumed that
the calling convention for this thunk was always __thiscall for 32-bit
targets and __cdecl for 64-bit targets.  However, this is not the case.
Mangle in whichever calling convention is appropriate for this member
function thunk.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232254 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp

index 6a0ebda7b33fa1028b9b1f5f33eb9f33596cf1b4..1b10fe3c2ebc3d90fb21961fb08739c46d898951 100644 (file)
@@ -583,7 +583,7 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
   Out << "$B";
   mangleNumber(OffsetInVFTable);
   Out << 'A';
-  Out << (PointersAre64Bit ? 'A' : 'E');
+  mangleCallingConvention(MD->getType()->getAs<FunctionProtoType>());
 }
 
 void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
index 0479f6aa69fb57594c3aed6552ca28bf97644f09..fe6468620b8cff123ba5499b7a01a2f9bd109998 100644 (file)
@@ -18,6 +18,7 @@ struct C {
   virtual int bar(int, double);
   virtual S baz(int);
   virtual S qux(U);
+  virtual void thud(...);
 };
 
 namespace {
@@ -43,6 +44,9 @@ void f() {
   S (C::*ptr5)(U);
   ptr5 = &C::qux;
 
+  void (C::*ptr6)(...);
+  ptr6 = &C::thud;
+
 
 // CHECK32-LABEL: define void @"\01?f@@YAXXZ"()
 // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr
@@ -148,4 +152,19 @@ void f() {
 // CHECK64: ret void
 // CHECK64: }
 
+// Thunk for calling the fifth virtual function in C which uses the __cdecl calling convention.
+// CHECK32-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BCA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64: ret void
+// CHECK64: }
+
 // CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}
index 896b768a93ed17f781666122ef4c0af65095ab7e..0b00ef5b585d65b8c099955a9d807aad640e1c41 100644 (file)
@@ -93,9 +93,9 @@ void f(C *c) {
 }
 
 // CHECK-LABEL: define void @"\01?f@cdecl_inalloca@@YAXPAUC@1@@Z"(%"struct.cdecl_inalloca::C"* %c)
-// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AE" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* %{{.*}})
-// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AE" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}})
+// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AA" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* %{{.*}})
+// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}})
 
-// CHECK-LABEL: define linkonce_odr void @"\01??_9C@cdecl_inalloca@@$BA@AE"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat
+// CHECK-LABEL: define linkonce_odr void @"\01??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat
 // CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...)* %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...)
 // CHECK-NEXT: ret void