1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSIZE 2 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - -Oz -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-SIZE 3 4 void t1(int *a) { 5 delete a; 6 } 7 8 struct S { 9 int a; 10 }; 11 12 // POD types. 13 14 // CHECK-LABEL: define void @_Z2t3P1S 15 void t3(S *s) { 16 // CHECK: icmp {{.*}} null 17 // CHECK: br i1 18 19 // CHECK: bitcast 20 // CHECK-NEXT: call void @_ZdlPv 21 22 // Check the delete is inside the 'if !null' check unless we're optimizing 23 // for size. FIXME: We could omit the branch entirely in this case. 24 // CHECK-NOSIZE-NEXT: br 25 // CHECK-SIZE-NEXT: ret 26 delete s; 27 } 28 29 // Non-POD 30 struct T { 31 ~T(); 32 int a; 33 }; 34 35 // CHECK-LABEL: define void @_Z2t4P1T 36 void t4(T *t) { 37 // CHECK: call void @_ZN1TD1Ev 38 // CHECK-NOSIZE-NEXT: bitcast 39 // CHECK-SIZE-NEXT: br 40 // CHECK-SIZE: bitcast 41 // CHECK-NEXT: call void @_ZdlPv 42 delete t; 43 } 44 45 // PR5102 46 template <typename T> 47 class A { 48 public: operator T *() const; 49 }; 50 51 void f() { 52 A<char*> a; 53 54 delete a; 55 } 56 57 namespace test0 { 58 struct A { 59 void *operator new(__SIZE_TYPE__ sz); 60 void operator delete(void *p) { ::operator delete(p); } 61 ~A() {} 62 }; 63 64 // CHECK-LABEL: define void @_ZN5test04testEPNS_1AE( 65 void test(A *a) { 66 // CHECK: call void @_ZN5test01AD1Ev 67 // CHECK-NOSIZE-NEXT: bitcast 68 // CHECK-SIZE-NEXT: br 69 // CHECK-SIZE: bitcast 70 // CHECK-NEXT: call void @_ZN5test01AdlEPv 71 delete a; 72 } 73 74 // CHECK-LABEL: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr 75 // CHECK-LABEL: define linkonce_odr void @_ZN5test01AdlEPv 76 } 77 78 namespace test1 { 79 struct A { 80 int x; 81 ~A(); 82 }; 83 84 // CHECK-LABEL: define void @_ZN5test14testEPA10_A20_NS_1AE( 85 void test(A (*arr)[10][20]) { 86 delete [] arr; 87 // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null 88 // CHECK-NEXT: br i1 89 90 // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0 91 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8* 92 // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 -8 93 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64* 94 // CHECK-NEXT: [[COUNT:%.*]] = load i64, i64* [[T1]] 95 // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 [[COUNT]] 96 // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]] 97 // CHECK-NEXT: br i1 [[ISEMPTY]], 98 // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 99 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1 100 // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]]) 101 // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] 102 // CHECK-NEXT: br i1 [[ISDONE]] 103 // CHECK: call void @_ZdaPv(i8* [[ALLOC]]) 104 } 105 } 106 107 namespace test2 { 108 // CHECK-LABEL: define void @_ZN5test21fEPb 109 void f(bool *b) { 110 // CHECK: call void @_ZdlPv(i8* 111 delete b; 112 // CHECK: call void @_ZdaPv(i8* 113 delete [] b; 114 } 115 } 116 117 namespace test3 { 118 void f(int a[10][20]) { 119 // CHECK: call void @_ZdaPv(i8* 120 delete a; 121 } 122 } 123 124 namespace test4 { 125 // PR10341: ::delete with a virtual destructor 126 struct X { 127 virtual ~X(); 128 void operator delete (void *); 129 }; 130 131 // CHECK-LABEL: define void @_ZN5test421global_delete_virtualEPNS_1XE 132 void global_delete_virtual(X *xp) { 133 // Load the offset-to-top from the vtable and apply it. 134 // This has to be done first because the dtor can mess it up. 135 // CHECK: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64** 136 // CHECK-NEXT: [[VTABLE:%.*]] = load i64*, i64** [[T0]] 137 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64, i64* [[VTABLE]], i64 -2 138 // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* [[T0]], align 8 139 // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8* 140 // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]] 141 // Load the complete-object destructor (not the deleting destructor) 142 // and call it. 143 // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)*** 144 // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)**, void ([[X]]*)*** [[T0]] 145 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)*, void ([[X]]*)** [[VTABLE]], i64 0 146 // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)*, void ([[X]]*)** [[T0]] 147 // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]]) 148 // Call the global operator delete. 149 // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) [[NUW:#[0-9]+]] 150 ::delete xp; 151 } 152 } 153 154 namespace test5 { 155 struct Incomplete; 156 // CHECK-LABEL: define void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_ 157 void array_delete_incomplete(Incomplete *p1, Incomplete *p2) { 158 // CHECK: call void @_ZdlPv 159 delete p1; 160 // CHECK: call void @_ZdaPv 161 delete [] p2; 162 } 163 } 164 165 // CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}} 166