brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.0 KiB · 24b1a4d Raw
306 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ITANIUM,CHECK-64BIT2// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT,CLANG22-MSABI,CLANG22-MSABI643// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT,CLANG22-MSABI,CLANG22-MSABI324// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -fclang-abi-compat=20 -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-32BIT,CHECK-MSABI32,CLANG21-MSABI,CLANG21-MSABI325// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -fclang-abi-compat=20 -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT,CLANG21-MSABI,CLANG21-MSABI646 7// PR46908: ensure the IR passes the verifier with optimizations enabled.8// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-linux-gnu -O29// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-windows -O210// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple i386-windows -O211 12namespace std {13  using size_t = decltype(sizeof(0));14  enum class align_val_t : size_t;15  struct destroying_delete_t {};16}17 18struct A {19  void *data;20  ~A();21  void operator delete(A*, std::destroying_delete_t);22};23void delete_A(A *a) { delete a; }24// CHECK-LABEL: define {{.*}}delete_A25// CHECK: %[[a:.*]] = load26// CHECK: icmp eq ptr %[[a]], null27// CHECK: br i128//29// Ensure that we call the destroying delete and not the destructor.30// CHECK-NOT: call31// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])32// CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i833// CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})34// CHECK-NOT: call35// CHECK: }36 37void glob_delete_A(A *a) { ::delete a; }38 39// CHECK-LABEL: define {{.*}}glob_delete_A40// CHECK: %[[a:.*]] = load41// CHECK: icmp eq ptr %[[a]], null42// CHECK: br i143 44// CHECK-ITANIUM: call void @_ZN1AD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %[[a]])45// CHECK-ITANIUM-NEXT: call void @_ZdlPvm(ptr noundef %[[a]], i64 noundef 8)46// CHECK-MSABI64: call void @"??1A@@QEAA@XZ"(ptr noundef nonnull align 8 dereferenceable(8) %[[a]])47// CHECK-MSABI64-NEXT: call void @"??3@YAXPEAX_K@Z"(ptr noundef %[[a]], i64 noundef 8)48// CHECK-MSABI32: call x86_thiscallcc void @"??1A@@QAE@XZ"(ptr noundef nonnull align 4 dereferenceable(4) %[[a]])49// CHECK-MSABI32-NEXT: call void @"??3@YAXPAXI@Z"(ptr noundef %[[a]], i32 noundef 4)50 51struct B {52  virtual ~B();53  void operator delete(B*, std::destroying_delete_t);54};55void delete_B(B *b) { delete b; }56// CHECK-LABEL: define {{.*}}delete_B57// CHECK: %[[b:.*]] = load58// CHECK: icmp eq ptr %[[b]], null59// CHECK: br i160//61// Ensure that we call the virtual destructor and not the operator delete.62// CHECK-NOT: call63// CHECK: %[[VTABLE:.*]] = load64// CHECK: %[[DTOR:.*]] = load65// CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr {{[^,]*}} %[[b]]66// CHECK-MSABI-SAME: , i32 noundef 1)67// CHECK-NOT: call68// CHECK: }69 70void glob_delete_B(B *b) { ::delete b; }71// CHECK-LABEL: define {{.*}}glob_delete_B72// CHECK: %[[b:.*]] = load73// CHECK: icmp eq ptr %[[b]], null74// CHECK: br i175 76// CHECK-NOT: call77// CHECK-MSABI: %[[VTABLE:.*]] = load78// CHECK-MSABI: %[[DTOR:.*]] = load79// CHECK-ITANIUM: %[[VTABLE:.*]] = load ptr, ptr %[[b]], align 880// CHECK-ITANIUM: %[[COMPLETEOFFSETPTR:.*]] = getelementptr inbounds i64, ptr %[[VTABLE]], i64 -281// CHECK-ITANIUM: %[[OFFSET:.*]] = load i64, ptr %[[COMPLETEOFFSETPTR]], align 882// CHECK-ITANIUM: %[[ALLOCATED:.*]] = getelementptr inbounds i8, ptr %[[b]], i64 %[[OFFSET]]83// CHECK-ITANIUM: %[[VTABLE1:.*]] = load ptr, ptr %[[b]], align 884// CHECK-ITANIUM: %[[DTOR_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE1]], i64 085// CHECK-ITANIUM: %[[DTOR:.*]] = load ptr, ptr %[[DTOR_ADDR]], align 886// CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr {{[^,]*}} %[[b]]87// CLANG22-MSABI-SAME: , i32 noundef 5)88// CLANG21-MSABI-SAME: , i32 noundef 0)89// CLANG22-MSABI-NOT: call90// CLANG21-MSABI64: call void @"??3@YAXPEAX_K@Z"({{.*}})91// CLANG21-MSABI32: call void @"??3@YAXPAXI@Z"({{.*}})92// CHECK-ITANIUM: call void @_ZdlPvm({{.*}})93// CHECK: }94 95struct Padding {96  virtual void f();97};98 99struct C : Padding, A {};100void delete_C(C *c) { delete c; }101// Check that we perform a derived-to-base conversion on the parameter to 'operator delete'.102// CHECK-LABEL: define {{.*}}delete_C103// CHECK: %[[c:.*]] = load104// CHECK: icmp eq ptr %[[c]], null105// CHECK: br i1106//107// CHECK-64BIT: %[[base:.*]] = getelementptr {{.*}}, i64 8108// CHECK-32BIT: %[[base:.*]] = getelementptr {{.*}}, i32 4109//110// CHECK: %[[a:.*]] = phi {{.*}} %[[base]]111// CHECK: icmp eq ptr %[[a]], null112// CHECK: br i1113//114// CHECK-NOT: call115// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])116// CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i8117// CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})118// CHECK-NOT: call119// CHECK: }120 121struct VDel { virtual ~VDel(); };122struct D : Padding, VDel, B {};123void delete_D(D *d) { delete d; }124// CHECK-LABEL: define {{.*}}delete_D125// CHECK: %[[d:.*]] = load126// CHECK: icmp eq ptr %[[d]], null127// CHECK: br i1128//129// CHECK-NOT: call130// For MS, we don't add a new vtable slot to the primary vtable for the virtual131// destructor. Instead we cast to the VDel base class.132// CHECK-MSABI64: %[[d:.*]] = getelementptr {{.*}}, i64 8133// CHECK-MSABI32: %[[d:.*]] = getelementptr {{.*}}, i32 4134//135// CHECK: %[[VTABLE:.*]] = load136// CHECK: %[[DTOR:.*]] = load137//138// CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr{{[^,]*}} %[[d]]139// CHECK-MSABI-SAME: , i32 noundef 1)140// CHECK-NOT: call141// CHECK: }142 143struct J {144  J(); // might throw145  void operator delete(J *, std::destroying_delete_t);146};147 148// CHECK-ITANIUM-LABEL: define {{.*}}@_Z1j149// CHECK-MSABI-LABEL: define {{.*}}@"?j@@150J *j() {151  // CHECK-ITANIUM: invoke {{.*}}@_ZN1JC1Ev(152  // CHECK-ITANIUM: call {{.*}}@_ZdlPvm(153  // CHECK-NOT: }154  // CHECK-MSABI: invoke {{.*}}@"??0J@@Q{{AE|EAA}}@XZ"(155  // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX{{I|_K}}@Z"(156  return new J;157  // CHECK: }158}159 160struct K {161  K(); // might throw162  void operator delete(void *);163  void operator delete(K *, std::destroying_delete_t);164};165 166// CHECK-ITANIUM-LABEL: define {{.*}}@_Z1k167// CHECK-MSABI-LABEL: define {{.*}}@"?k@@168K *k() {169  // CHECK-ITANIUM: invoke {{.*}}@_ZN1KC1Ev(170  // CHECK-ITANIUM: call {{.*}}@_ZN1KdlEPv(171  // CHECK-NOT: }172  // CHECK-MSABI: invoke {{.*}}@"??0K@@Q{{AE|EAA}}@XZ"(173  // CHECK-MSABI: call {{.*}}@"??3K@@SAXP{{E?}}AX@Z"(174  return new K;175  // CHECK: }176}177 178struct E { void *data; };179struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; };180struct alignas(16) G : E, F { void *data; };181 182void delete_G(G *g) { delete g; }183// CHECK-LABEL: define {{.*}}delete_G184// CHECK-NOT: call185// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(ptr noundef %[[a]], i64 noundef 32, i64 noundef 16)186// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(ptr noundef %[[a]], i8 {{[^,]*}}, i64 noundef 32, i64 noundef 16)187// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}}, i32 noundef 16, i32 noundef 16)188// CHECK-NOT: call189// CHECK: }190 191void call_in_dtor();192 193struct H : G { virtual ~H(); } h;194H::~H() { call_in_dtor(); }195// CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1HD0Ev(196// CHECK-ITANIUM-NOT: call197// CHECK-ITANIUM: getelementptr {{.*}}, i64 24198// CHECK-ITANIUM-NOT: call199// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 48, i64 noundef 16)200// CHECK-ITANIUM-NOT: call201// CHECK-ITANIUM: }202 203// CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"({{.*}},204// CHECK-MSABI32-LABEL: define {{.*}} @"??_GH@@UAEPAXI@Z"(205// CHECK-MSABI-SAME: i32 noundef %[[IP:.*]])206// CHECK-MSABI-NOT: call{{ }}207// CHECK-MSABI: store i32 %[[IP]], ptr %[[IP_ALLOCA:.*]]208// CHECK-MSABI: %[[IMP_PARAM:.*]] = load i32, ptr %[[IP_ALLOCA]]209// CLANG22: %[[THIRDBIT:.*]] = and i32 %[[IMP_PARAM]], 4210// CLANG22-NEXT: %[[CHCK:.*]] = icmp eq i32 %[[THIRDBIT]], 0211// CLANG22-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor212// CLANG21-MSABI: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1213// CLANG21-MSABI: %[[CHCK:.*]] = icmp eq i32 %[[FIRSTBIT]], 0214// CLANG21-MSABI: br i1 %[[CHCK]], label %dtor.continue, label %dtor.call_delete215//216// CLANG22-MSABI: dtor.call_dtor:217// CLANG22-MSABI64-NEXT: call void @"??1H@@UEAA@XZ"({{.*}})218// CLANG22-MSABI32-NEXT: call x86_thiscallcc void @"??1H@@UAE@XZ"({{.*}})219// CLANG22-MSABI-NEXT: br label %dtor.entry_cont220//221// CLANG22-MSABI-LABEL: dtor.entry_cont:222// CLANG22-MSABI-NEXT: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1223// CLANG22-MSABI-NEXT: %[[CHCK1:.*]] = icmp eq i32 %[[FIRSTBIT]], 0224// CLANG22-MSABI-NEXT: br i1 %[[CHCK1]], label %dtor.continue, label %dtor.call_delete225//226// CLANG22-MSABI-LABEL: dtor.call_delete:227// CLANG22-MSABI: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4228// CLANG22-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0229// CLANG22-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete230//231// CLANG22-MSABI-LABEL: dtor.call_glob_delete:232// CLANG22-MSABI64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %{{.*}}, i64 noundef 48)233// CLANG22-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 32, i32 noundef 16)234// CLANG22-MSABI-NEXT: br label %[[RETURN:.*]]235//236// CLANG21-MSABI: dtor.call_delete:237// CLANG22-MSABI: dtor.call_class_delete:238// CLANG22-MSABI-NOT: call{{ }}239// CLANG22-MSABI64: getelementptr {{.*}}, i64 24240// CLANG22-MSABI32: getelementptr {{.*}}, i32 20241// CLANG22-MSABI-NOT: call{{ }}242// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16)243// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16)244// CHECK-MSABI: br label %[[RETURN:]]245//246// CHECK-MSABI: dtor.continue:247// CHECK-MSABI64: call void @"??1H@@UEAA@XZ"(248// CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"(249// CHECK-MSABI: br label %[[RETURN]]250//251// CHECK-MSABI: }252 253struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i;254I::~I() { call_in_dtor(); }255// CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1ID0Ev(256// CHECK-ITANIUM-NOT: call257// CHECK-ITANIUM: getelementptr {{.*}}, i64 24258// CHECK-ITANIUM-NOT: call259// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 96, i64 noundef 32)260// CHECK-ITANIUM-NOT: call261// CHECK-ITANIUM: }262 263// CHECK-MSABI64-LABEL: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(264// CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"(265// CHECK-MSABI-NOT: call{{ }}266// CHECK-MSABI: load i32267// CLANG22-MSABI-NEXT: and i32 %[[IMP_PARAM:.*]], 4268// CLANG22-MSABI-NEXT: icmp eq i32 {{.*}}, 0269// CLANG22-MSABI-NEXT: br i1 %{{.*}}, label %dtor.entry_cont, label %dtor.call_dtor270//271// CLANG22-MSABI: dtor.call_dtor:272// CLANG22-MSABI64-NEXT: call void @"??1I@@UEAA@XZ"({{.*}})273// CLANG22-MSABI32-NEXT: call x86_thiscallcc void @"??1I@@UAE@XZ"({{.*}})274// CLANG22-MSABI-NEXT: br label %dtor.entry_cont275//276// CLANG22-MSABI: dtor.entry_cont:277// CLANG22-MSABI-NEXT: and i32 %[[IMP_PARAM]], 1278// CLANG22-MSABI-NEXT: icmp eq i32 %{{.*}}, 0279// CLANG22-MSABI-NEXT: br i1 %{{.*}}, label %dtor.continue, label %dtor.call_delete280//281// CLANG22-MSABI: dtor.call_delete:282// CLANG22-MSABI-NEXT: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4283// CLANG22-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0284// CLANG22-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete285//286// CLANG22-MSABI: dtor.call_glob_delete:287// CLANG22-MSABI64: call void @"??3@YAXPEAX_KW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i64 noundef 96, i64 noundef 32)288// CLANG22-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 64, i32 noundef 32)289// CLANG22-MSABI-NEXT: br label %[[RETURN:.*]]290//291// CLANG21-MSABI: dtor.call_delete:292// CLANG22-MSABI: dtor.call_class_delete:293// CHECK-MSABI-NOT: call{{ }}294// CHECK-MSABI64: getelementptr {{.*}}, i64 24295// CHECK-MSABI32: getelementptr {{.*}}, i32 20296// CHECK-MSABI-NOT: call{{ }}297// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 96, i64 noundef 32)298// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 64, i32 noundef 32)299// CHECK-MSABI: br label %[[RETURN:.*]]300//301// CHECK-MSABI64: call void @"??1I@@UEAA@XZ"(302// CHECK-MSABI32: call x86_thiscallcc void @"??1I@@UAE@XZ"(303// CHECK-MSABI: br label %[[RETURN]]304//305// CHECK-MSABI: }306