1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
2 
3 #define NULL ((void *)0)
4 
5 int gi;
6 
7 typedef unsigned long size_t;
8 
9 // CHECK-DAG-RE: define void @my_malloc({{.*}}) #[[MALLOC_ATTR_NUMBER:[0-9]+]]
10 // N.B. LLVM's allocsize arguments are base-0, whereas ours are base-1 (for
11 // compat with GCC)
12 // CHECK-DAG-RE: attributes #[[MALLOC_ATTR_NUMBER]] = {.*allocsize(0).*}
13 void *my_malloc(size_t) __attribute__((alloc_size(1)));
14 
15 // CHECK-DAG-RE: define void @my_calloc({{.*}}) #[[CALLOC_ATTR_NUMBER:[0-9]+]]
16 // CHECK-DAG-RE: attributes #[[CALLOC_ATTR_NUMBER]] = {.*allocsize(0, 1).*}
17 void *my_calloc(size_t, size_t) __attribute__((alloc_size(1, 2)));
18 
19 // CHECK-LABEL: @test1
20 void test1() {
21   void *const vp = my_malloc(100);
22   // CHECK: store i32 100
23   gi = __builtin_object_size(vp, 0);
24   // CHECK: store i32 100
25   gi = __builtin_object_size(vp, 1);
26   // CHECK: store i32 100
27   gi = __builtin_object_size(vp, 2);
28   // CHECK: store i32 100
29   gi = __builtin_object_size(vp, 3);
30 
31   void *const arr = my_calloc(100, 5);
32   // CHECK: store i32 500
33   gi = __builtin_object_size(arr, 0);
34   // CHECK: store i32 500
35   gi = __builtin_object_size(arr, 1);
36   // CHECK: store i32 500
37   gi = __builtin_object_size(arr, 2);
38   // CHECK: store i32 500
39   gi = __builtin_object_size(arr, 3);
40 
41   // CHECK: store i32 100
42   gi = __builtin_object_size(my_malloc(100), 0);
43   // CHECK: store i32 100
44   gi = __builtin_object_size(my_malloc(100), 1);
45   // CHECK: store i32 100
46   gi = __builtin_object_size(my_malloc(100), 2);
47   // CHECK: store i32 100
48   gi = __builtin_object_size(my_malloc(100), 3);
49 
50   // CHECK: store i32 500
51   gi = __builtin_object_size(my_calloc(100, 5), 0);
52   // CHECK: store i32 500
53   gi = __builtin_object_size(my_calloc(100, 5), 1);
54   // CHECK: store i32 500
55   gi = __builtin_object_size(my_calloc(100, 5), 2);
56   // CHECK: store i32 500
57   gi = __builtin_object_size(my_calloc(100, 5), 3);
58 
59   void *const zeroPtr = my_malloc(0);
60   // CHECK: store i32 0
61   gi = __builtin_object_size(zeroPtr, 0);
62   // CHECK: store i32 0
63   gi = __builtin_object_size(my_malloc(0), 0);
64 
65   void *const zeroArr1 = my_calloc(0, 1);
66   void *const zeroArr2 = my_calloc(1, 0);
67   // CHECK: store i32 0
68   gi = __builtin_object_size(zeroArr1, 0);
69   // CHECK: store i32 0
70   gi = __builtin_object_size(zeroArr2, 0);
71   // CHECK: store i32 0
72   gi = __builtin_object_size(my_calloc(1, 0), 0);
73   // CHECK: store i32 0
74   gi = __builtin_object_size(my_calloc(0, 1), 0);
75 }
76 
77 // CHECK-LABEL: @test2
78 void test2() {
79   void *const vp = my_malloc(gi);
80   // CHECK: @llvm.objectsize
81   gi = __builtin_object_size(vp, 0);
82 
83   void *const arr1 = my_calloc(gi, 1);
84   // CHECK: @llvm.objectsize
85   gi = __builtin_object_size(arr1, 0);
86 
87   void *const arr2 = my_calloc(1, gi);
88   // CHECK: @llvm.objectsize
89   gi = __builtin_object_size(arr2, 0);
90 }
91 
92 // CHECK-LABEL: @test3
93 void test3() {
94   char *const buf = (char *)my_calloc(100, 5);
95   // CHECK: store i32 500
96   gi = __builtin_object_size(buf, 0);
97   // CHECK: store i32 500
98   gi = __builtin_object_size(buf, 1);
99   // CHECK: store i32 500
100   gi = __builtin_object_size(buf, 2);
101   // CHECK: store i32 500
102   gi = __builtin_object_size(buf, 3);
103 }
104 
105 struct Data {
106   int a;
107   int t[10];
108   char pad[3];
109   char end[1];
110 };
111 
112 // CHECK-LABEL: @test5
113 void test5() {
114   struct Data *const data = my_malloc(sizeof(*data));
115   // CHECK: store i32 48
116   gi = __builtin_object_size(data, 0);
117   // CHECK: store i32 48
118   gi = __builtin_object_size(data, 1);
119   // CHECK: store i32 48
120   gi = __builtin_object_size(data, 2);
121   // CHECK: store i32 48
122   gi = __builtin_object_size(data, 3);
123 
124   // CHECK: store i32 40
125   gi = __builtin_object_size(&data->t[1], 0);
126   // CHECK: store i32 36
127   gi = __builtin_object_size(&data->t[1], 1);
128   // CHECK: store i32 40
129   gi = __builtin_object_size(&data->t[1], 2);
130   // CHECK: store i32 36
131   gi = __builtin_object_size(&data->t[1], 3);
132 
133   struct Data *const arr = my_calloc(sizeof(*data), 2);
134   // CHECK: store i32 96
135   gi = __builtin_object_size(arr, 0);
136   // CHECK: store i32 96
137   gi = __builtin_object_size(arr, 1);
138   // CHECK: store i32 96
139   gi = __builtin_object_size(arr, 2);
140   // CHECK: store i32 96
141   gi = __builtin_object_size(arr, 3);
142 
143   // CHECK: store i32 88
144   gi = __builtin_object_size(&arr->t[1], 0);
145   // CHECK: store i32 36
146   gi = __builtin_object_size(&arr->t[1], 1);
147   // CHECK: store i32 88
148   gi = __builtin_object_size(&arr->t[1], 2);
149   // CHECK: store i32 36
150   gi = __builtin_object_size(&arr->t[1], 3);
151 }
152 
153 // CHECK-LABEL: @test6
154 void test6() {
155   // Things that would normally trigger conservative estimates don't need to do
156   // so when we know the source of the allocation.
157   struct Data *const data = my_malloc(sizeof(*data) + 10);
158   // CHECK: store i32 11
159   gi = __builtin_object_size(data->end, 0);
160   // CHECK: store i32 11
161   gi = __builtin_object_size(data->end, 1);
162   // CHECK: store i32 11
163   gi = __builtin_object_size(data->end, 2);
164   // CHECK: store i32 11
165   gi = __builtin_object_size(data->end, 3);
166 
167   struct Data *const arr = my_calloc(sizeof(*arr) + 5, 3);
168   // AFAICT, GCC treats malloc and calloc identically. So, we should do the
169   // same.
170   //
171   // Additionally, GCC ignores the initial array index when determining whether
172   // we're writing off the end of an alloc_size base. e.g.
173   //   arr[0].end
174   //   arr[1].end
175   //   arr[2].end
176   // ...Are all considered "writing off the end", because there's no way to tell
177   // with high accuracy if the user meant "allocate a single N-byte `Data`",
178   // or "allocate M smaller `Data`s with extra padding".
179 
180   // CHECK: store i32 112
181   gi = __builtin_object_size(arr->end, 0);
182   // CHECK: store i32 112
183   gi = __builtin_object_size(arr->end, 1);
184   // CHECK: store i32 112
185   gi = __builtin_object_size(arr->end, 2);
186   // CHECK: store i32 112
187   gi = __builtin_object_size(arr->end, 3);
188 
189   // CHECK: store i32 112
190   gi = __builtin_object_size(arr[0].end, 0);
191   // CHECK: store i32 112
192   gi = __builtin_object_size(arr[0].end, 1);
193   // CHECK: store i32 112
194   gi = __builtin_object_size(arr[0].end, 2);
195   // CHECK: store i32 112
196   gi = __builtin_object_size(arr[0].end, 3);
197 
198   // CHECK: store i32 64
199   gi = __builtin_object_size(arr[1].end, 0);
200   // CHECK: store i32 64
201   gi = __builtin_object_size(arr[1].end, 1);
202   // CHECK: store i32 64
203   gi = __builtin_object_size(arr[1].end, 2);
204   // CHECK: store i32 64
205   gi = __builtin_object_size(arr[1].end, 3);
206 
207   // CHECK: store i32 16
208   gi = __builtin_object_size(arr[2].end, 0);
209   // CHECK: store i32 16
210   gi = __builtin_object_size(arr[2].end, 1);
211   // CHECK: store i32 16
212   gi = __builtin_object_size(arr[2].end, 2);
213   // CHECK: store i32 16
214   gi = __builtin_object_size(arr[2].end, 3);
215 }
216 
217 // CHECK-LABEL: @test7
218 void test7() {
219   struct Data *const data = my_malloc(sizeof(*data) + 5);
220   // CHECK: store i32 9
221   gi = __builtin_object_size(data->pad, 0);
222   // CHECK: store i32 3
223   gi = __builtin_object_size(data->pad, 1);
224   // CHECK: store i32 9
225   gi = __builtin_object_size(data->pad, 2);
226   // CHECK: store i32 3
227   gi = __builtin_object_size(data->pad, 3);
228 }
229 
230 // CHECK-LABEL: @test8
231 void test8() {
232   // Non-const pointers aren't currently supported.
233   void *buf = my_calloc(100, 5);
234   // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
235   gi = __builtin_object_size(buf, 0);
236   // CHECK: @llvm.objectsize
237   gi = __builtin_object_size(buf, 1);
238   // CHECK: @llvm.objectsize
239   gi = __builtin_object_size(buf, 2);
240   // CHECK: store i32 0
241   gi = __builtin_object_size(buf, 3);
242 }
243 
244 // CHECK-LABEL: @test9
245 void test9() {
246   // Check to be sure that we unwrap things correctly.
247   short *const buf0 = (my_malloc(100));
248   short *const buf1 = (short*)(my_malloc(100));
249   short *const buf2 = ((short*)(my_malloc(100)));
250 
251   // CHECK: store i32 100
252   gi = __builtin_object_size(buf0, 0);
253   // CHECK: store i32 100
254   gi = __builtin_object_size(buf1, 0);
255   // CHECK: store i32 100
256   gi = __builtin_object_size(buf2, 0);
257 }
258 
259 // CHECK-LABEL: @test10
260 void test10() {
261   // Yay overflow
262   short *const arr = my_calloc((size_t)-1 / 2 + 1, 2);
263   // CHECK: @llvm.objectsize
264   gi = __builtin_object_size(arr, 0);
265   // CHECK: @llvm.objectsize
266   gi = __builtin_object_size(arr, 1);
267   // CHECK: @llvm.objectsize
268   gi = __builtin_object_size(arr, 2);
269   // CHECK: store i32 0
270   gi = __builtin_object_size(arr, 3);
271 
272   // As an implementation detail, CharUnits can't handle numbers greater than or
273   // equal to 2**63. Realistically, this shouldn't be a problem, but we should
274   // be sure we don't emit crazy results for this case.
275   short *const buf = my_malloc((size_t)-1);
276   // CHECK: @llvm.objectsize
277   gi = __builtin_object_size(buf, 0);
278   // CHECK: @llvm.objectsize
279   gi = __builtin_object_size(buf, 1);
280   // CHECK: @llvm.objectsize
281   gi = __builtin_object_size(buf, 2);
282   // CHECK: store i32 0
283   gi = __builtin_object_size(buf, 3);
284 
285   short *const arr_big = my_calloc((size_t)-1 / 2 - 1, 2);
286   // CHECK: @llvm.objectsize
287   gi = __builtin_object_size(arr_big, 0);
288   // CHECK: @llvm.objectsize
289   gi = __builtin_object_size(arr_big, 1);
290   // CHECK: @llvm.objectsize
291   gi = __builtin_object_size(arr_big, 2);
292   // CHECK: store i32 0
293   gi = __builtin_object_size(arr_big, 3);
294 }
295 
296 void *my_tiny_malloc(char) __attribute__((alloc_size(1)));
297 void *my_tiny_calloc(char, char) __attribute__((alloc_size(1, 2)));
298 
299 // CHECK-LABEL: @test11
300 void test11() {
301   void *const vp = my_tiny_malloc(100);
302   // CHECK: store i32 100
303   gi = __builtin_object_size(vp, 0);
304   // CHECK: store i32 100
305   gi = __builtin_object_size(vp, 1);
306   // CHECK: store i32 100
307   gi = __builtin_object_size(vp, 2);
308   // CHECK: store i32 100
309   gi = __builtin_object_size(vp, 3);
310 
311   // N.B. This causes char overflow, but not size_t overflow, so it should be
312   // supported.
313   void *const arr = my_tiny_calloc(100, 5);
314   // CHECK: store i32 500
315   gi = __builtin_object_size(arr, 0);
316   // CHECK: store i32 500
317   gi = __builtin_object_size(arr, 1);
318   // CHECK: store i32 500
319   gi = __builtin_object_size(arr, 2);
320   // CHECK: store i32 500
321   gi = __builtin_object_size(arr, 3);
322 }
323 
324 void *my_signed_malloc(long) __attribute__((alloc_size(1)));
325 void *my_signed_calloc(long, long) __attribute__((alloc_size(1, 2)));
326 
327 // CHECK-LABEL: @test12
328 void test12() {
329   // CHECK: store i32 100
330   gi = __builtin_object_size(my_signed_malloc(100), 0);
331   // CHECK: store i32 500
332   gi = __builtin_object_size(my_signed_calloc(100, 5), 0);
333 
334   void *const vp = my_signed_malloc(-2);
335   // CHECK: @llvm.objectsize
336   gi = __builtin_object_size(vp, 0);
337   // N.B. These get lowered to -1 because the function calls may have
338   // side-effects, and we can't determine the objectsize.
339   // CHECK: store i32 -1
340   gi = __builtin_object_size(my_signed_malloc(-2), 0);
341 
342   void *const arr1 = my_signed_calloc(-2, 1);
343   void *const arr2 = my_signed_calloc(1, -2);
344   // CHECK: @llvm.objectsize
345   gi = __builtin_object_size(arr1, 0);
346   // CHECK: @llvm.objectsize
347   gi = __builtin_object_size(arr2, 0);
348   // CHECK: store i32 -1
349   gi = __builtin_object_size(my_signed_calloc(1, -2), 0);
350   // CHECK: store i32 -1
351   gi = __builtin_object_size(my_signed_calloc(-2, 1), 0);
352 }
353