1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 | FileCheck %s 2 3 typedef unsigned long size_t; 4 5 struct Foo { 6 int t[10]; 7 }; 8 9 #define PS(N) __attribute__((pass_object_size(N))) 10 #define PDS(N) __attribute__((pass_dynamic_object_size(N))) 11 12 int gi = 0; 13 14 // CHECK-LABEL: define{{.*}} i32 @ObjectSize0(i8* %{{.*}}, i64 %0) 15 int ObjectSize0(void *const p PS(0)) { 16 // CHECK-NOT: @llvm.objectsize 17 return __builtin_object_size(p, 0); 18 } 19 20 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize0(i8* %{{.*}}, i64 %0) 21 int DynamicObjectSize0(void *const p PDS(0)) { 22 // CHECK-NOT: @llvm.objectsize 23 return __builtin_dynamic_object_size(p, 0); 24 } 25 26 // CHECK-LABEL: define{{.*}} i32 @ObjectSize1(i8* %{{.*}}, i64 %0) 27 int ObjectSize1(void *const p PS(1)) { 28 // CHECK-NOT: @llvm.objectsize 29 return __builtin_object_size(p, 1); 30 } 31 32 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize1(i8* %{{.*}}, i64 %0) 33 int DynamicObjectSize1(void *const p PDS(1)) { 34 // CHECK-NOT: @llvm.objectsize 35 return __builtin_dynamic_object_size(p, 1); 36 } 37 38 // CHECK-LABEL: define{{.*}} i32 @ObjectSize2(i8* %{{.*}}, i64 %0) 39 int ObjectSize2(void *const p PS(2)) { 40 // CHECK-NOT: @llvm.objectsize 41 return __builtin_object_size(p, 2); 42 } 43 44 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize2(i8* %{{.*}}, i64 %0) 45 int DynamicObjectSize2(void *const p PDS(2)) { 46 // CHECK-NOT: @llvm.objectsize 47 return __builtin_object_size(p, 2); 48 } 49 50 // CHECK-LABEL: define{{.*}} i32 @ObjectSize3(i8* %{{.*}}, i64 %0) 51 int ObjectSize3(void *const p PS(3)) { 52 // CHECK-NOT: @llvm.objectsize 53 return __builtin_object_size(p, 3); 54 } 55 56 // CHECK-LABEL: define{{.*}} i32 @DynamicObjectSize3(i8* %{{.*}}, i64 %0) 57 int DynamicObjectSize3(void *const p PDS(3)) { 58 // CHECK-NOT: @llvm.objectsize 59 return __builtin_object_size(p, 3); 60 } 61 62 void *malloc(unsigned long) __attribute__((alloc_size(1))); 63 64 // CHECK-LABEL: define{{.*}} void @test1 65 void test1(unsigned long sz) { 66 struct Foo t[10]; 67 68 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360) 69 gi = ObjectSize0(&t[1]); 70 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 360) 71 gi = ObjectSize1(&t[1]); 72 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 360) 73 gi = ObjectSize2(&t[1]); 74 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 360) 75 gi = ObjectSize3(&t[1]); 76 77 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 356) 78 gi = ObjectSize0(&t[1].t[1]); 79 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36) 80 gi = ObjectSize1(&t[1].t[1]); 81 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 356) 82 gi = ObjectSize2(&t[1].t[1]); 83 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) 84 gi = ObjectSize3(&t[1].t[1]); 85 86 char *ptr = (char *)malloc(sz); 87 88 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 false, i1 true, i1 true) 89 // CHECK: call i32 @DynamicObjectSize0(i8* %{{.*}}, i64 [[REG]]) 90 gi = DynamicObjectSize0(ptr); 91 92 // CHECK: [[WITH_OFFSET:%.*]] = getelementptr 93 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[WITH_OFFSET]], i1 false, i1 true, i1 true) 94 // CHECK: call i32 @DynamicObjectSize0(i8* {{.*}}, i64 [[REG]]) 95 gi = DynamicObjectSize0(ptr+10); 96 97 // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 true, i1 true, i1 true) 98 // CHECK: call i32 @DynamicObjectSize2(i8* {{.*}}, i64 [[REG]]) 99 gi = DynamicObjectSize2(ptr); 100 } 101 102 // CHECK-LABEL: define{{.*}} void @test2 103 void test2(struct Foo *t) { 104 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize 105 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 [[VAR]]) 106 gi = ObjectSize1(&t->t[1]); 107 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) 108 gi = ObjectSize3(&t->t[1]); 109 } 110 111 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize0Pv 112 int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) { 113 // CHECK: @llvm.objectsize 114 return __builtin_object_size(p, 0); 115 } 116 117 // CHECK-LABEL: define{{.*}} i32 @_Z34NoViableOverloadDynamicObjectSize0Pv 118 int NoViableOverloadDynamicObjectSize0(void *const p) 119 __attribute__((overloadable)) { 120 // CHECK: @llvm.objectsize 121 return __builtin_object_size(p, 0); 122 } 123 124 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize1Pv 125 int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) { 126 // CHECK: @llvm.objectsize 127 return __builtin_object_size(p, 1); 128 } 129 130 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize2Pv 131 int NoViableOverloadObjectSize2(void *const p) __attribute__((overloadable)) { 132 // CHECK: @llvm.objectsize 133 return __builtin_object_size(p, 2); 134 } 135 136 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize3Pv 137 int NoViableOverloadObjectSize3(void *const p) __attribute__((overloadable)) { 138 // CHECK-NOT: @llvm.objectsize 139 return __builtin_object_size(p, 3); 140 } 141 142 // CHECK-LABEL: define{{.*}} i32 @_Z27NoViableOverloadObjectSize0Pv 143 // CHECK-NOT: @llvm.objectsize 144 int NoViableOverloadObjectSize0(void *const p PS(0)) 145 __attribute__((overloadable)) { 146 return __builtin_object_size(p, 0); 147 } 148 149 int NoViableOverloadDynamicObjectSize0(void *const p PDS(0)) 150 __attribute__((overloadable)) { 151 return __builtin_dynamic_object_size(p, 0); 152 } 153 154 int NoViableOverloadObjectSize1(void *const p PS(1)) 155 __attribute__((overloadable)) { 156 return __builtin_object_size(p, 1); 157 } 158 159 int NoViableOverloadObjectSize2(void *const p PS(2)) 160 __attribute__((overloadable)) { 161 return __builtin_object_size(p, 2); 162 } 163 164 int NoViableOverloadObjectSize3(void *const p PS(3)) 165 __attribute__((overloadable)) { 166 return __builtin_object_size(p, 3); 167 } 168 169 const static int SHOULDNT_BE_CALLED = -100; 170 int NoViableOverloadObjectSize0(void *const p PS(0)) 171 __attribute__((overloadable, enable_if(p == 0, "never selected"))) { 172 return SHOULDNT_BE_CALLED; 173 } 174 175 int NoViableOverloadObjectSize1(void *const p PS(1)) 176 __attribute__((overloadable, enable_if(p == 0, "never selected"))) { 177 return SHOULDNT_BE_CALLED; 178 } 179 180 int NoViableOverloadObjectSize2(void *const p PS(2)) 181 __attribute__((overloadable, enable_if(p == 0, "never selected"))) { 182 return SHOULDNT_BE_CALLED; 183 } 184 185 int NoViableOverloadObjectSize3(void *const p PS(3)) 186 __attribute__((overloadable, enable_if(p == 0, "never selected"))) { 187 return SHOULDNT_BE_CALLED; 188 } 189 190 // CHECK-LABEL: define{{.*}} void @test3 191 void test3() { 192 struct Foo t[10]; 193 194 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 360) 195 gi = NoViableOverloadObjectSize0(&t[1]); 196 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 360) 197 gi = NoViableOverloadObjectSize1(&t[1]); 198 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 360) 199 gi = NoViableOverloadObjectSize2(&t[1]); 200 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 360) 201 gi = NoViableOverloadObjectSize3(&t[1]); 202 203 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 356) 204 gi = NoViableOverloadObjectSize0(&t[1].t[1]); 205 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36) 206 gi = NoViableOverloadObjectSize1(&t[1].t[1]); 207 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 356) 208 gi = NoViableOverloadObjectSize2(&t[1].t[1]); 209 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) 210 gi = NoViableOverloadObjectSize3(&t[1].t[1]); 211 212 // CHECK: call i32 @_Z34NoViableOverloadDynamicObjectSize0PvU25pass_dynamic_object_size0(i8* %{{.*}}, i64 360) 213 gi = NoViableOverloadDynamicObjectSize0(&t[1]); 214 } 215 216 // CHECK-LABEL: define{{.*}} void @test4 217 void test4(struct Foo *t) { 218 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) 219 gi = NoViableOverloadObjectSize0(&t[1]); 220 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 %{{.*}}) 221 gi = NoViableOverloadObjectSize1(&t[1]); 222 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) 223 gi = NoViableOverloadObjectSize2(&t[1]); 224 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 0) 225 gi = NoViableOverloadObjectSize3(&t[1]); 226 227 // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) 228 gi = NoViableOverloadObjectSize0(&t[1].t[1]); 229 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize 230 // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 [[VAR]]) 231 gi = NoViableOverloadObjectSize1(&t[1].t[1]); 232 // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) 233 gi = NoViableOverloadObjectSize2(&t[1].t[1]); 234 // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) 235 gi = NoViableOverloadObjectSize3(&t[1].t[1]); 236 } 237 238 void test5() { 239 struct Foo t[10]; 240 241 int (*f)(void *) = &NoViableOverloadObjectSize0; 242 gi = f(&t[1]); 243 244 int (*g)(void *) = &NoViableOverloadDynamicObjectSize0; 245 gi = g(&t[1]); 246 } 247 248 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize0 249 int IndirectObjectSize0(void *const p PS(0)) { 250 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}}) 251 // CHECK-NOT: @llvm.objectsize 252 return ObjectSize0(p); 253 } 254 255 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize1 256 int IndirectObjectSize1(void *const p PS(1)) { 257 // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 %{{.*}}) 258 // CHECK-NOT: @llvm.objectsize 259 return ObjectSize1(p); 260 } 261 262 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize2 263 int IndirectObjectSize2(void *const p PS(2)) { 264 // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 %{{.*}}) 265 // CHECK-NOT: @llvm.objectsize 266 return ObjectSize2(p); 267 } 268 269 // CHECK-LABEL: define{{.*}} i32 @IndirectObjectSize3 270 int IndirectObjectSize3(void *const p PS(3)) { 271 // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 %{{.*}}) 272 // CHECK-NOT: @llvm.objectsize 273 return ObjectSize3(p); 274 } 275 276 int IndirectDynamicObjectSize0(void *const p PDS(0)) { 277 // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}}) 278 // CHECK-NOT: @llvm.objectsize 279 return ObjectSize0(p); 280 } 281 282 int Overload0(void *, size_t, void *, size_t); 283 int OverloadNoSize(void *, void *); 284 285 int OverloadedObjectSize(void *const p PS(0), 286 void *const c PS(0)) 287 __attribute__((overloadable)) __asm__("Overload0"); 288 289 int OverloadedObjectSize(void *const p, void *const c) 290 __attribute__((overloadable)) __asm__("OverloadNoSize"); 291 292 // CHECK-LABEL: define{{.*}} void @test6 293 void test6() { 294 int known[10], *opaque; 295 296 // CHECK: call i32 @"\01Overload0" 297 gi = OverloadedObjectSize(&known[0], &known[0]); 298 299 // CHECK: call i32 @"\01Overload0" 300 gi = OverloadedObjectSize(&known[0], opaque); 301 302 // CHECK: call i32 @"\01Overload0" 303 gi = OverloadedObjectSize(opaque, &known[0]); 304 305 // CHECK: call i32 @"\01Overload0" 306 gi = OverloadedObjectSize(opaque, opaque); 307 } 308 309 int Identity(void *p, size_t i) { return i; } 310 311 // CHECK-NOT: define{{.*}} void @AsmObjectSize 312 int AsmObjectSize0(void *const p PS(0)) __asm__("Identity"); 313 314 int AsmObjectSize1(void *const p PS(1)) __asm__("Identity"); 315 316 int AsmObjectSize2(void *const p PS(2)) __asm__("Identity"); 317 318 int AsmObjectSize3(void *const p PS(3)) __asm__("Identity"); 319 320 // CHECK-LABEL: define{{.*}} void @test7 321 void test7() { 322 struct Foo t[10]; 323 324 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) 325 gi = AsmObjectSize0(&t[1]); 326 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) 327 gi = AsmObjectSize1(&t[1]); 328 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) 329 gi = AsmObjectSize2(&t[1]); 330 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) 331 gi = AsmObjectSize3(&t[1]); 332 333 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) 334 gi = AsmObjectSize0(&t[1].t[1]); 335 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) 336 gi = AsmObjectSize1(&t[1].t[1]); 337 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) 338 gi = AsmObjectSize2(&t[1].t[1]); 339 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) 340 gi = AsmObjectSize3(&t[1].t[1]); 341 } 342 343 // CHECK-LABEL: define{{.*}} void @test8 344 void test8(struct Foo *t) { 345 // CHECK: [[VAR:%[0-9]+]] = call i64 @llvm.objectsize 346 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 [[VAR]]) 347 gi = AsmObjectSize1(&t[1].t[1]); 348 // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) 349 gi = AsmObjectSize3(&t[1].t[1]); 350 } 351 352 void DifferingObjectSize0(void *const p __attribute__((pass_object_size(0)))); 353 void DifferingObjectSize1(void *const p __attribute__((pass_object_size(1)))); 354 void DifferingObjectSize2(void *const p __attribute__((pass_object_size(2)))); 355 void DifferingObjectSize3(void *const p __attribute__((pass_object_size(3)))); 356 357 // CHECK-LABEL: define{{.*}} void @test9 358 void test9(void *const p __attribute__((pass_object_size(0)))) { 359 // CHECK: @llvm.objectsize 360 DifferingObjectSize2(p); 361 362 // CHECK-NOT: @llvm.objectsize 363 DifferingObjectSize0(p); 364 DifferingObjectSize1(p); 365 366 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) 367 DifferingObjectSize3(p); 368 } 369 370 // CHECK-LABEL: define{{.*}} void @test10 371 void test10(void *const p __attribute__((pass_object_size(1)))) { 372 // CHECK: @llvm.objectsize 373 DifferingObjectSize2(p); 374 // CHECK: @llvm.objectsize 375 DifferingObjectSize0(p); 376 377 // CHECK-NOT: @llvm.objectsize 378 DifferingObjectSize1(p); 379 380 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) 381 DifferingObjectSize3(p); 382 } 383 384 // CHECK-LABEL: define{{.*}} void @test11 385 void test11(void *const p __attribute__((pass_object_size(2)))) { 386 // CHECK: @llvm.objectsize 387 DifferingObjectSize0(p); 388 // CHECK: @llvm.objectsize 389 DifferingObjectSize1(p); 390 391 // CHECK-NOT: @llvm.objectsize 392 DifferingObjectSize2(p); 393 394 // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) 395 DifferingObjectSize3(p); 396 } 397 398 // CHECK-LABEL: define{{.*}} void @test12 399 void test12(void *const p __attribute__((pass_object_size(3)))) { 400 // CHECK: @llvm.objectsize 401 DifferingObjectSize0(p); 402 // CHECK: @llvm.objectsize 403 DifferingObjectSize1(p); 404 405 // CHECK-NOT: @llvm.objectsize 406 DifferingObjectSize2(p); 407 DifferingObjectSize3(p); 408 } 409 410 // CHECK-LABEL: define{{.*}} void @test13 411 void test13() { 412 char c[10]; 413 unsigned i = 0; 414 char *p = c; 415 416 // CHECK: @llvm.objectsize 417 ObjectSize0(p); 418 419 // Allow side-effects, since they always need to happen anyway. Just make sure 420 // we don't perform them twice. 421 // CHECK: = add 422 // CHECK-NOT: = add 423 // CHECK: @llvm.objectsize 424 // CHECK: call i32 @ObjectSize0 425 ObjectSize0(p + ++i); 426 427 // CHECK: = add 428 // CHECK: @llvm.objectsize 429 // CHECK-NOT: = add 430 // CHECK: call i32 @ObjectSize0 431 ObjectSize0(p + i++); 432 } 433 434 // There was a bug where variadic functions with pass_object_size would cause 435 // problems in the form of failed assertions. 436 void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {} 437 438 // CHECK-LABEL: define{{.*}} void @test14 439 void test14(char *c) { 440 // CHECK: @llvm.objectsize 441 // CHECK: call void (i8*, i64, ...) @my_sprintf 442 my_sprintf(c); 443 444 // CHECK: @llvm.objectsize 445 // CHECK: call void (i8*, i64, ...) @my_sprintf 446 my_sprintf(c, 1, 2, 3); 447 } 448 449 void pass_size_unsigned(unsigned *const PS(0)); 450 451 // Bug: we weren't lowering to the proper @llvm.objectsize for pointers that 452 // don't turn into i8*s, which caused crashes. 453 // CHECK-LABEL: define{{.*}} void @test15 454 void test15(unsigned *I) { 455 // CHECK: @llvm.objectsize.i64.p0i32 456 // CHECK: call void @pass_size_unsigned 457 pass_size_unsigned(I); 458 } 459 460 void pass_size_as1(__attribute__((address_space(1))) void *const PS(0)); 461 462 void pass_size_unsigned_as1( 463 __attribute__((address_space(1))) unsigned *const PS(0)); 464 465 // CHECK-LABEL: define{{.*}} void @test16 466 void test16(__attribute__((address_space(1))) unsigned *I) { 467 // CHECK: call i64 @llvm.objectsize.i64.p1i8 468 // CHECK: call void @pass_size_as1 469 pass_size_as1(I); 470 // CHECK: call i64 @llvm.objectsize.i64.p1i32 471 // CHECK: call void @pass_size_unsigned_as1 472 pass_size_unsigned_as1(I); 473 } 474 475 // This used to cause assertion failures, since we'd try to emit the statement 476 // expression (and definitions for `a`) twice. 477 // CHECK-LABEL: define{{.*}} void @test17 478 void test17(char *C) { 479 // Check for 65535 to see if we're emitting this pointer twice. 480 // CHECK: 65535 481 // CHECK-NOT: 65535 482 // CHECK: @llvm.objectsize.i64.p0i8(i8* [[PTR:%[^,]+]], 483 // CHECK-NOT: 65535 484 // CHECK: call i32 @ObjectSize0(i8* [[PTR]] 485 ObjectSize0(C + ({ int a = 65535; a; })); 486 } 487 488 // CHECK-LABEL: define{{.*}} void @test18 489 void test18(char *const p PDS(0)) { 490 // CHECK-NOT: llvm.objectsize 491 gi = __builtin_dynamic_object_size(p, 0); 492 gi = __builtin_object_size(p, 0); 493 } 494