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