494 lines · c
1// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s2// RUN: %clang_cc1 -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s3 4#ifdef DYNAMIC5#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size6#else7#define OBJECT_SIZE_BUILTIN __builtin_object_size8#endif9 10#define NULL ((void *)0)11 12int gi;13 14typedef unsigned long size_t;15 16// CHECK-DAG-RE: define void @my_malloc({{.*}}) #[[MALLOC_ATTR_NUMBER:[0-9]+]]17// N.B. LLVM's allocsize arguments are base-0, whereas ours are base-1 (for18// compat with GCC)19// CHECK-DAG-RE: attributes #[[MALLOC_ATTR_NUMBER]] = {.*allocsize(0).*}20void *my_malloc(size_t) __attribute__((alloc_size(1)));21 22// CHECK-DAG-RE: define void @my_calloc({{.*}}) #[[CALLOC_ATTR_NUMBER:[0-9]+]]23// CHECK-DAG-RE: attributes #[[CALLOC_ATTR_NUMBER]] = {.*allocsize(0, 1).*}24void *my_calloc(size_t, size_t) __attribute__((alloc_size(1, 2)));25 26// CHECK-LABEL: @test127void test1(void) {28 void *const vp = my_malloc(100);29 // CHECK: store i32 10030 gi = OBJECT_SIZE_BUILTIN(vp, 0);31 // CHECK: store i32 10032 gi = OBJECT_SIZE_BUILTIN(vp, 1);33 // CHECK: store i32 10034 gi = OBJECT_SIZE_BUILTIN(vp, 2);35 // CHECK: store i32 10036 gi = OBJECT_SIZE_BUILTIN(vp, 3);37 38 void *const arr = my_calloc(100, 5);39 // CHECK: store i32 50040 gi = OBJECT_SIZE_BUILTIN(arr, 0);41 // CHECK: store i32 50042 gi = OBJECT_SIZE_BUILTIN(arr, 1);43 // CHECK: store i32 50044 gi = OBJECT_SIZE_BUILTIN(arr, 2);45 // CHECK: store i32 50046 gi = OBJECT_SIZE_BUILTIN(arr, 3);47 48 // CHECK: store i32 10049 gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 0);50 // CHECK: store i32 10051 gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 1);52 // CHECK: store i32 10053 gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 2);54 // CHECK: store i32 10055 gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 3);56 57 // CHECK: store i32 50058 gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 0);59 // CHECK: store i32 50060 gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 1);61 // CHECK: store i32 50062 gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 2);63 // CHECK: store i32 50064 gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 3);65 66 void *const zeroPtr = my_malloc(0);67 // CHECK: store i32 068 gi = OBJECT_SIZE_BUILTIN(zeroPtr, 0);69 // CHECK: store i32 070 gi = OBJECT_SIZE_BUILTIN(my_malloc(0), 0);71 72 void *const zeroArr1 = my_calloc(0, 1);73 void *const zeroArr2 = my_calloc(1, 0);74 // CHECK: store i32 075 gi = OBJECT_SIZE_BUILTIN(zeroArr1, 0);76 // CHECK: store i32 077 gi = OBJECT_SIZE_BUILTIN(zeroArr2, 0);78 // CHECK: store i32 079 gi = OBJECT_SIZE_BUILTIN(my_calloc(1, 0), 0);80 // CHECK: store i32 081 gi = OBJECT_SIZE_BUILTIN(my_calloc(0, 1), 0);82}83 84// CHECK-LABEL: @test285void test2(void) {86 void *const vp = my_malloc(gi);87 // CHECK: @llvm.objectsize88 gi = OBJECT_SIZE_BUILTIN(vp, 0);89 90 void *const arr1 = my_calloc(gi, 1);91 // CHECK: @llvm.objectsize92 gi = OBJECT_SIZE_BUILTIN(arr1, 0);93 94 void *const arr2 = my_calloc(1, gi);95 // CHECK: @llvm.objectsize96 gi = OBJECT_SIZE_BUILTIN(arr2, 0);97}98 99// CHECK-LABEL: @test3100void test3(void) {101 char *const buf = (char *)my_calloc(100, 5);102 // CHECK: store i32 500103 gi = OBJECT_SIZE_BUILTIN(buf, 0);104 // CHECK: store i32 500105 gi = OBJECT_SIZE_BUILTIN(buf, 1);106 // CHECK: store i32 500107 gi = OBJECT_SIZE_BUILTIN(buf, 2);108 // CHECK: store i32 500109 gi = OBJECT_SIZE_BUILTIN(buf, 3);110}111 112struct Data {113 int a;114 int t[10];115 char pad[3];116 char end[1];117};118 119// CHECK-LABEL: @test5120void test5(void) {121 struct Data *const data = my_malloc(sizeof(*data));122 // CHECK: store i32 48123 gi = OBJECT_SIZE_BUILTIN(data, 0);124 // CHECK: store i32 48125 gi = OBJECT_SIZE_BUILTIN(data, 1);126 // CHECK: store i32 48127 gi = OBJECT_SIZE_BUILTIN(data, 2);128 // CHECK: store i32 48129 gi = OBJECT_SIZE_BUILTIN(data, 3);130 131 // CHECK: store i32 40132 gi = OBJECT_SIZE_BUILTIN(&data->t[1], 0);133 // CHECK: store i32 36134 gi = OBJECT_SIZE_BUILTIN(&data->t[1], 1);135 // CHECK: store i32 40136 gi = OBJECT_SIZE_BUILTIN(&data->t[1], 2);137 // CHECK: store i32 36138 gi = OBJECT_SIZE_BUILTIN(&data->t[1], 3);139 140 struct Data *const arr = my_calloc(2, sizeof(*data));141 // CHECK: store i32 96142 gi = OBJECT_SIZE_BUILTIN(arr, 0);143 // CHECK: store i32 96144 gi = OBJECT_SIZE_BUILTIN(arr, 1);145 // CHECK: store i32 96146 gi = OBJECT_SIZE_BUILTIN(arr, 2);147 // CHECK: store i32 96148 gi = OBJECT_SIZE_BUILTIN(arr, 3);149 150 // CHECK: store i32 88151 gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 0);152 // CHECK: store i32 36153 gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 1);154 // CHECK: store i32 88155 gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 2);156 // CHECK: store i32 36157 gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 3);158}159 160// CHECK-LABEL: @test6161void test6(void) {162 // Things that would normally trigger conservative estimates don't need to do163 // so when we know the source of the allocation.164 struct Data *const data = my_malloc(sizeof(*data) + 10);165 // CHECK: store i32 11166 gi = OBJECT_SIZE_BUILTIN(data->end, 0);167 // CHECK: store i32 11168 gi = OBJECT_SIZE_BUILTIN(data->end, 1);169 // CHECK: store i32 11170 gi = OBJECT_SIZE_BUILTIN(data->end, 2);171 // CHECK: store i32 11172 gi = OBJECT_SIZE_BUILTIN(data->end, 3);173 174 struct Data *const arr = my_calloc(3, sizeof(*arr) + 5);175 // AFAICT, GCC treats malloc and calloc identically. So, we should do the176 // same.177 //178 // Additionally, GCC ignores the initial array index when determining whether179 // we're writing off the end of an alloc_size base. e.g.180 // arr[0].end181 // arr[1].end182 // arr[2].end183 // ...Are all considered "writing off the end", because there's no way to tell184 // with high accuracy if the user meant "allocate a single N-byte `Data`",185 // or "allocate M smaller `Data`s with extra padding".186 187 // CHECK: store i32 112188 gi = OBJECT_SIZE_BUILTIN(arr->end, 0);189 // CHECK: store i32 112190 gi = OBJECT_SIZE_BUILTIN(arr->end, 1);191 // CHECK: store i32 112192 gi = OBJECT_SIZE_BUILTIN(arr->end, 2);193 // CHECK: store i32 112194 gi = OBJECT_SIZE_BUILTIN(arr->end, 3);195 196 // CHECK: store i32 112197 gi = OBJECT_SIZE_BUILTIN(arr[0].end, 0);198 // CHECK: store i32 112199 gi = OBJECT_SIZE_BUILTIN(arr[0].end, 1);200 // CHECK: store i32 112201 gi = OBJECT_SIZE_BUILTIN(arr[0].end, 2);202 // CHECK: store i32 112203 gi = OBJECT_SIZE_BUILTIN(arr[0].end, 3);204 205 // CHECK: store i32 64206 gi = OBJECT_SIZE_BUILTIN(arr[1].end, 0);207 // CHECK: store i32 64208 gi = OBJECT_SIZE_BUILTIN(arr[1].end, 1);209 // CHECK: store i32 64210 gi = OBJECT_SIZE_BUILTIN(arr[1].end, 2);211 // CHECK: store i32 64212 gi = OBJECT_SIZE_BUILTIN(arr[1].end, 3);213 214 // CHECK: store i32 16215 gi = OBJECT_SIZE_BUILTIN(arr[2].end, 0);216 // CHECK: store i32 16217 gi = OBJECT_SIZE_BUILTIN(arr[2].end, 1);218 // CHECK: store i32 16219 gi = OBJECT_SIZE_BUILTIN(arr[2].end, 2);220 // CHECK: store i32 16221 gi = OBJECT_SIZE_BUILTIN(arr[2].end, 3);222}223 224// CHECK-LABEL: @test7225void test7(void) {226 struct Data *const data = my_malloc(sizeof(*data) + 5);227 // CHECK: store i32 9228 gi = OBJECT_SIZE_BUILTIN(data->pad, 0);229 // CHECK: store i32 3230 gi = OBJECT_SIZE_BUILTIN(data->pad, 1);231 // CHECK: store i32 9232 gi = OBJECT_SIZE_BUILTIN(data->pad, 2);233 // CHECK: store i32 3234 gi = OBJECT_SIZE_BUILTIN(data->pad, 3);235}236 237// CHECK-LABEL: @test8238void test8(void) {239 // Non-const pointers aren't currently supported.240 void *buf = my_calloc(100, 5);241 // CHECK: @llvm.objectsize.i64.p0(ptr %{{.*}}, i1 false, i1 true, i1242 gi = OBJECT_SIZE_BUILTIN(buf, 0);243 // CHECK: @llvm.objectsize244 gi = OBJECT_SIZE_BUILTIN(buf, 1);245 // CHECK: @llvm.objectsize246 gi = OBJECT_SIZE_BUILTIN(buf, 2);247 // CHECK: store i32 0248 gi = OBJECT_SIZE_BUILTIN(buf, 3);249}250 251// CHECK-LABEL: @test9252void test9(void) {253 // Check to be sure that we unwrap things correctly.254 short *const buf0 = (my_malloc(100));255 short *const buf1 = (short*)(my_malloc(100));256 short *const buf2 = ((short*)(my_malloc(100)));257 258 // CHECK: store i32 100259 gi = OBJECT_SIZE_BUILTIN(buf0, 0);260 // CHECK: store i32 100261 gi = OBJECT_SIZE_BUILTIN(buf1, 0);262 // CHECK: store i32 100263 gi = OBJECT_SIZE_BUILTIN(buf2, 0);264}265 266// CHECK-LABEL: @test10267void test10(void) {268 // Yay overflow269 short *const arr = my_calloc((size_t)-1 / 2 + 1, 2);270 // CHECK: @llvm.objectsize271 gi = OBJECT_SIZE_BUILTIN(arr, 0);272 // CHECK: @llvm.objectsize273 gi = OBJECT_SIZE_BUILTIN(arr, 1);274 // CHECK: @llvm.objectsize275 gi = OBJECT_SIZE_BUILTIN(arr, 2);276 // CHECK: store i32 0277 gi = OBJECT_SIZE_BUILTIN(arr, 3);278 279 // As an implementation detail, CharUnits can't handle numbers greater than or280 // equal to 2**63. Realistically, this shouldn't be a problem, but we should281 // be sure we don't emit crazy results for this case.282 short *const buf = my_malloc((size_t)-1);283 // CHECK: @llvm.objectsize284 gi = OBJECT_SIZE_BUILTIN(buf, 0);285 // CHECK: @llvm.objectsize286 gi = OBJECT_SIZE_BUILTIN(buf, 1);287 // CHECK: @llvm.objectsize288 gi = OBJECT_SIZE_BUILTIN(buf, 2);289 // CHECK: store i32 0290 gi = OBJECT_SIZE_BUILTIN(buf, 3);291 292 short *const arr_big = my_calloc((size_t)-1 / 2 - 1, 2);293 // CHECK: @llvm.objectsize294 gi = OBJECT_SIZE_BUILTIN(arr_big, 0);295 // CHECK: @llvm.objectsize296 gi = OBJECT_SIZE_BUILTIN(arr_big, 1);297 // CHECK: @llvm.objectsize298 gi = OBJECT_SIZE_BUILTIN(arr_big, 2);299 // CHECK: store i32 0300 gi = OBJECT_SIZE_BUILTIN(arr_big, 3);301}302 303void *my_tiny_malloc(char) __attribute__((alloc_size(1)));304void *my_tiny_calloc(char, char) __attribute__((alloc_size(1, 2)));305 306// CHECK-LABEL: @test11307void test11(void) {308 void *const vp = my_tiny_malloc(100);309 // CHECK: store i32 100310 gi = OBJECT_SIZE_BUILTIN(vp, 0);311 // CHECK: store i32 100312 gi = OBJECT_SIZE_BUILTIN(vp, 1);313 // CHECK: store i32 100314 gi = OBJECT_SIZE_BUILTIN(vp, 2);315 // CHECK: store i32 100316 gi = OBJECT_SIZE_BUILTIN(vp, 3);317 318 // N.B. This causes char overflow, but not size_t overflow, so it should be319 // supported.320 void *const arr = my_tiny_calloc(100, 5);321 // CHECK: store i32 500322 gi = OBJECT_SIZE_BUILTIN(arr, 0);323 // CHECK: store i32 500324 gi = OBJECT_SIZE_BUILTIN(arr, 1);325 // CHECK: store i32 500326 gi = OBJECT_SIZE_BUILTIN(arr, 2);327 // CHECK: store i32 500328 gi = OBJECT_SIZE_BUILTIN(arr, 3);329}330 331void *my_signed_malloc(long) __attribute__((alloc_size(1)));332void *my_signed_calloc(long, long) __attribute__((alloc_size(1, 2)));333 334// CHECK-LABEL: @test12335void test12(void) {336 // CHECK: store i32 100337 gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(100), 0);338 // CHECK: store i32 500339 gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(100, 5), 0);340 341 void *const vp = my_signed_malloc(-2);342 // CHECK: @llvm.objectsize343 gi = OBJECT_SIZE_BUILTIN(vp, 0);344 // N.B. These get lowered to -1 because the function calls may have345 // side-effects, and we can't determine the objectsize.346 // CHECK: store i32 -1347 gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(-2), 0);348 349 void *const arr1 = my_signed_calloc(-2, 1);350 void *const arr2 = my_signed_calloc(1, -2);351 // CHECK: @llvm.objectsize352 gi = OBJECT_SIZE_BUILTIN(arr1, 0);353 // CHECK: @llvm.objectsize354 gi = OBJECT_SIZE_BUILTIN(arr2, 0);355 // CHECK: store i32 -1356 gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(1, -2), 0);357 // CHECK: store i32 -1358 gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(-2, 1), 0);359}360 361void *alloc_uchar(unsigned char) __attribute__((alloc_size(1)));362 363// CHECK-LABEL: @test13364void test13(void) {365 // If 128 were incorrectly seen as negative, the result would become -1.366 // CHECK: store i32 128,367 gi = OBJECT_SIZE_BUILTIN(alloc_uchar(128), 0);368}369 370void *(*malloc_function_pointer)(int)__attribute__((alloc_size(1)));371void *(*calloc_function_pointer)(int, int)__attribute__((alloc_size(1, 2)));372 373// CHECK-LABEL: @test_fn_pointer374void test_fn_pointer(void) {375 void *const vp = malloc_function_pointer(100);376 // CHECK: store i32 100377 gi = __builtin_object_size(vp, 0);378 // CHECK: store i32 100379 gi = __builtin_object_size(vp, 1);380 // CHECK: store i32 100381 gi = __builtin_object_size(vp, 2);382 // CHECK: store i32 100383 gi = __builtin_object_size(vp, 3);384 385 void *const arr = calloc_function_pointer(100, 5);386 // CHECK: store i32 500387 gi = __builtin_object_size(arr, 0);388 // CHECK: store i32 500389 gi = __builtin_object_size(arr, 1);390 // CHECK: store i32 500391 gi = __builtin_object_size(arr, 2);392 // CHECK: store i32 500393 gi = __builtin_object_size(arr, 3);394 395 // CHECK: store i32 100396 gi = __builtin_object_size(malloc_function_pointer(100), 0);397 // CHECK: store i32 100398 gi = __builtin_object_size(malloc_function_pointer(100), 1);399 // CHECK: store i32 100400 gi = __builtin_object_size(malloc_function_pointer(100), 2);401 // CHECK: store i32 100402 gi = __builtin_object_size(malloc_function_pointer(100), 3);403 404 // CHECK: store i32 500405 gi = __builtin_object_size(calloc_function_pointer(100, 5), 0);406 // CHECK: store i32 500407 gi = __builtin_object_size(calloc_function_pointer(100, 5), 1);408 // CHECK: store i32 500409 gi = __builtin_object_size(calloc_function_pointer(100, 5), 2);410 // CHECK: store i32 500411 gi = __builtin_object_size(calloc_function_pointer(100, 5), 3);412 413 void *const zeroPtr = malloc_function_pointer(0);414 // CHECK: store i32 0415 gi = __builtin_object_size(zeroPtr, 0);416 // CHECK: store i32 0417 gi = __builtin_object_size(malloc_function_pointer(0), 0);418 419 void *const zeroArr1 = calloc_function_pointer(0, 1);420 void *const zeroArr2 = calloc_function_pointer(1, 0);421 // CHECK: store i32 0422 gi = __builtin_object_size(zeroArr1, 0);423 // CHECK: store i32 0424 gi = __builtin_object_size(zeroArr2, 0);425 // CHECK: store i32 0426 gi = __builtin_object_size(calloc_function_pointer(1, 0), 0);427 // CHECK: store i32 0428 gi = __builtin_object_size(calloc_function_pointer(0, 1), 0);429}430 431typedef void *(__attribute__((warn_unused_result, alloc_size(1))) * my_malloc_function_pointer_type)(int);432typedef void *(__attribute__((alloc_size(1, 2))) * my_calloc_function_pointer_type)(int, int);433extern my_malloc_function_pointer_type malloc_function_pointer_with_typedef;434extern my_calloc_function_pointer_type calloc_function_pointer_with_typedef;435 436// CHECK-LABEL: @test_fn_pointer_typedef437void test_fn_pointer_typedef(void) {438 malloc_function_pointer_with_typedef(100);439 void *const vp = malloc_function_pointer_with_typedef(100);440 // CHECK: store i32 100441 gi = __builtin_object_size(vp, 0);442 // CHECK: store i32 100443 gi = __builtin_object_size(vp, 1);444 // CHECK: store i32 100445 gi = __builtin_object_size(vp, 2);446 // CHECK: store i32 100447 gi = __builtin_object_size(vp, 3);448 449 void *const arr = calloc_function_pointer_with_typedef(100, 5);450 // CHECK: store i32 500451 gi = __builtin_object_size(arr, 0);452 // CHECK: store i32 500453 gi = __builtin_object_size(arr, 1);454 // CHECK: store i32 500455 gi = __builtin_object_size(arr, 2);456 // CHECK: store i32 500457 gi = __builtin_object_size(arr, 3);458 459 // CHECK: store i32 100460 gi = __builtin_object_size(malloc_function_pointer_with_typedef(100), 0);461 // CHECK: store i32 100462 gi = __builtin_object_size(malloc_function_pointer_with_typedef(100), 1);463 // CHECK: store i32 100464 gi = __builtin_object_size(malloc_function_pointer_with_typedef(100), 2);465 // CHECK: store i32 100466 gi = __builtin_object_size(malloc_function_pointer_with_typedef(100), 3);467 468 // CHECK: store i32 500469 gi = __builtin_object_size(calloc_function_pointer_with_typedef(100, 5), 0);470 // CHECK: store i32 500471 gi = __builtin_object_size(calloc_function_pointer_with_typedef(100, 5), 1);472 // CHECK: store i32 500473 gi = __builtin_object_size(calloc_function_pointer_with_typedef(100, 5), 2);474 // CHECK: store i32 500475 gi = __builtin_object_size(calloc_function_pointer_with_typedef(100, 5), 3);476 477 void *const zeroPtr = malloc_function_pointer_with_typedef(0);478 // CHECK: store i32 0479 gi = __builtin_object_size(zeroPtr, 0);480 // CHECK: store i32 0481 gi = __builtin_object_size(malloc_function_pointer_with_typedef(0), 0);482 483 void *const zeroArr1 = calloc_function_pointer_with_typedef(0, 1);484 void *const zeroArr2 = calloc_function_pointer_with_typedef(1, 0);485 // CHECK: store i32 0486 gi = __builtin_object_size(zeroArr1, 0);487 // CHECK: store i32 0488 gi = __builtin_object_size(zeroArr2, 0);489 // CHECK: store i32 0490 gi = __builtin_object_size(calloc_function_pointer_with_typedef(1, 0), 0);491 // CHECK: store i32 0492 gi = __builtin_object_size(calloc_function_pointer_with_typedef(0, 1), 0);493}494