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