190 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK322// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK643 4struct S {5 int x, y, z;6};7 8// U is not trivially copyable, and requires inalloca to pass by value.9struct U {10 int u;11 U();12 ~U();13 U(const U &);14};15 16struct B;17 18struct C {19 virtual void foo();20 virtual int bar(int, double);21 virtual S baz(int);22 virtual S qux(U);23 virtual void thud(...);24 virtual void (B::*plugh())();25};26 27namespace {28struct D {29 virtual void foo();30};31}32 33void f() {34 void (C::*ptr)();35 ptr = &C::foo;36 ptr = &C::foo; // Don't crash trying to define the thunk twice :)37 38 int (C::*ptr2)(int, double);39 ptr2 = &C::bar;40 41 S (C::*ptr3)(int);42 ptr3 = &C::baz;43 44 void (D::*ptr4)();45 ptr4 = &D::foo;46 47 S (C::*ptr5)(U);48 ptr5 = &C::qux;49 50 void (C::*ptr6)(...);51 ptr6 = &C::thud;52 53 auto ptr7 = &C::plugh;54 55 56// CHECK32-LABEL: define dso_local void @"?f@@YAXXZ"()57// CHECK32: store ptr @"??_9C@@$BA@AE", ptr %ptr58// CHECK32: store ptr @"??_9C@@$B3AE", ptr %ptr259// CHECK32: store ptr @"??_9C@@$B7AE", ptr %ptr360// CHECK32: store ptr @"??_9D@?A0x{{[^@]*}}@@$BA@AE", ptr %ptr461// CHECK32: }62//63// CHECK64-LABEL: define dso_local void @"?f@@YAXXZ"()64// CHECK64: store ptr @"??_9C@@$BA@AA", ptr %ptr65// CHECK64: store ptr @"??_9C@@$B7AA", ptr %ptr266// CHECK64: store ptr @"??_9C@@$BBA@AA", ptr %ptr367// CHECK64: store ptr @"??_9D@?A0x{{[^@]*}}@@$BA@AA", ptr %ptr68// CHECK64: }69}70 71 72// Thunk for calling the 1st virtual function in C with no parameters.73// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BA@AE"(ptr noundef %this, ...)74// CHECK32: #[[ATTR:[0-9]+]]75// CHECK32-NOT: unnamed_addr76// CHECK32: comdat77// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 078// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]79// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)80// CHECK32-NEXT: ret void81// CHECK32: }82//83// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BA@AA"(ptr noundef %this, ...)84// CHECK64: #[[ATTR:[0-9]+]]85// CHECK64-NOT: unnamed_addr86// CHECK64: comdat87// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 088// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]89// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)90// CHECK64-NEXT: ret void91// CHECK64: }92 93// Thunk for calling the 2nd virtual function in C, taking int and double as parameters, returning int.94// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B3AE"(ptr noundef %this, ...)95// CHECK32: #[[ATTR]] comdat96// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 197// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]98// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)99// CHECK32-NEXT: ret void100// CHECK32: }101//102// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$B7AA"(ptr noundef %this, ...)103// CHECK64: #[[ATTR]] comdat104// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 1105// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]106// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)107// CHECK64-NEXT: ret void108// CHECK64: }109 110// Thunk for calling the 3rd virtual function in C, taking an int parameter, returning a struct.111// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B7AE"(ptr noundef %this, ...)112// CHECK32: #[[ATTR]] comdat113// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 2114// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]115// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)116// CHECK32-NEXT: ret void117// CHECK32: }118//119// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(ptr noundef %this, ...)120// CHECK64: #[[ATTR]] comdat121// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 2122// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]123// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)124// CHECK64-NEXT: ret void125// CHECK64: }126 127// Thunk for calling the virtual function in internal class D.128// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A0x{{[^@]*}}@@$BA@AE"(ptr noundef %this, ...)129// CHECK32: #[[ATTR]]130// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 0131// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]132// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)133// CHECK32-NEXT: ret void134// CHECK32: }135//136// CHECK64-LABEL: define internal void @"??_9D@?A0x{{[^@]*}}@@$BA@AA"(ptr noundef %this, ...)137// CHECK64: #[[ATTR]]138// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 0139// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]140// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)141// CHECK64-NEXT: ret void142// CHECK64: }143 144// Thunk for calling the fourth virtual function in C, taking a struct parameter145// and returning a struct.146// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BM@AE"(ptr noundef %this, ...) {{.*}} comdat147// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 3148// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]149// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)150// CHECK32-NEXT: ret void151// CHECK32: }152//153// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBI@AA"(ptr noundef %this, ...) {{.*}} comdat154// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 3155// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]156// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)157// CHECK64: ret void158// CHECK64: }159 160// Thunk for calling the fifth virtual function in C which uses the __cdecl calling convention.161// CHECK32-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(ptr noundef %this, ...) {{.*}} comdat align 2 {162// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 4163// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]164// CHECK32: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)165// CHECK32: ret void166// CHECK32: }167//168// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BCA@AA"(ptr noundef %this, ...) {{.*}} comdat align 2 {169// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 4170// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]171// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)172// CHECK64: ret void173// CHECK64: }174 175// CHECK32: define linkonce_odr x86_thiscallcc void @"??_9C@@$BBE@AE"(ptr noundef %this, ...) {{.*}} comdat align 2 {176// CHECK32: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 5177// CHECK32: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]178// CHECK32: musttail call x86_thiscallcc void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)179// CHECK32: ret void180// CHECK32: }181 182// CHECK64: define linkonce_odr void @"??_9C@@$BCI@AA"(ptr noundef %this, ...) {{.*}} comdat align 2 {183// CHECK64: [[VPTR:%.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i64 5184// CHECK64: [[CALLEE:%.*]] = load ptr, ptr [[VPTR]]185// CHECK64: musttail call void (ptr, ...) [[CALLEE]](ptr noundef %{{.*}}, ...)186// CHECK64: ret void187// CHECK64: }188 189// CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}190