1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s 2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-GLOBALS %s 3 4// CHECK: define void @test0 5void test0(id x) { 6 // CHECK: [[X:%.*]] = alloca i8* 7 // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{.*}}) 8 // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] 9 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]] 10 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) 11 // CHECK-NEXT: ret void 12// rdar://12040837 13 // CHECK: declare extern_weak i8* @objc_retain(i8*) nonlazybind 14 // CHECK: declare extern_weak void @objc_release(i8*) nonlazybind 15} 16 17// CHECK: define i8* @test1(i8* 18id test1(id x) { 19 // CHECK: [[X:%.*]] = alloca i8* 20 // CHECK-NEXT: [[Y:%.*]] = alloca i8* 21 // CHECK-NEXT: alloca i32 22 // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}}) 23 // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] 24 // CHECK-NEXT: store i8* null, i8** [[Y]] 25 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 26 // CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T0]]) 27 // CHECK-NEXT: store i32 28 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 29 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 30 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 31 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 32 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[RET]]) 33 // CHECK-NEXT: ret i8* [[T1]] 34 id y; 35 return y; 36} 37 38@interface Test2 39+ (void) class_method; 40- (void) inst_method; 41@end 42@implementation Test2 43 44// The self pointer of a class method is not retained. 45// CHECK: define internal void @"\01+[Test2 class_method]" 46// CHECK: alloca 47// CHECK-NEXT: alloca 48// CHECK-NEXT: store 49// CHECK-NEXT: store 50// CHECK-NEXT: ret void 51+ (void) class_method {} 52 53// The self pointer of an instance method is not retained. 54// CHECK: define internal void @"\01-[Test2 inst_method]" 55// CHECK: alloca 56// CHECK-NEXT: alloca 57// CHECK-NEXT: store 58// CHECK-NEXT: store 59// CHECK-NEXT: ret void 60- (void) inst_method {} 61@end 62 63@interface Test3 64+ (id) alloc; 65- (id) initWith: (int) x; 66- (id) copy; 67@end 68 69// CHECK: define void @test3_unelided() 70void test3_unelided() { 71 extern void test3_helper(void); 72 73 // CHECK: [[X:%.*]] = alloca [[TEST3:%.*]]* 74 // CHECK-NEXT: store [[TEST3]]* null, [[TEST3]]** [[X]], align 75 Test3 *x; 76 77 // Call to +alloc. 78 // CHECK-NEXT: load {{.*}}* @"\01L_OBJC_CLASSLIST_REFERENCES_ 79 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 80 // CHECK-NEXT: bitcast 81 // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 82 // CHECK-NEXT: bitcast 83 // CHECK-NEXT: bitcast 84 // CHECK-NEXT: call void @objc_release(i8* 85 [Test3 alloc]; 86 87 // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[X]] 88 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 89 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* 90 // CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* [[T1]], 91 // CHECK-NEXT: call void @objc_release(i8* [[COPY]]) nounwind 92 [x copy]; 93 94 // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[X]] 95 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8* 96 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind 97 // CHECK-NEXT: ret void 98} 99 100// CHECK: define void @test3() 101void test3() { 102 // CHECK: [[X:%.*]] = alloca i8* 103 104 id x = [[Test3 alloc] initWith: 5]; 105 106 // Call to +alloc. 107 // CHECK-NEXT: load {{.*}}* @"\01L_OBJC_CLASSLIST_REFERENCES_ 108 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 109 // CHECK-NEXT: bitcast 110 // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 111 // CHECK-NEXT: bitcast 112 113 // Call to -initWith: with elided retain of consumed argument. 114 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 115 // CHECK-NEXT: bitcast 116 // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* 117 // CHECK-NEXT: bitcast 118 // CHECK-NEXT: [[INIT:%.*]] = bitcast 119 // Assignment for initialization, retention elided. 120 // CHECK-NEXT: store i8* [[INIT]], i8** [[X]] 121 122 // Call to -copy. 123 // CHECK-NEXT: [[V:%.*]] = load i8** [[X]] 124 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 125 // CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* [[V]], 126 127 // Assignment to x. 128 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]] 129 // CHECK-NEXT: store i8* [[COPY]], i8** [[X]] 130 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind 131 132 x = [x copy]; 133 134 // Cleanup for x. 135 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]] 136 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind 137 138 // CHECK-NEXT: ret void 139} 140 141// CHECK: define i8* @test4() 142id test4() { 143 // Call to +alloc. 144 // CHECK: load {{.*}}* @"\01L_OBJC_CLASSLIST_REFERENCES_ 145 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 146 // CHECK-NEXT: bitcast 147 // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 148 // CHECK-NEXT: [[ALLOC:%.*]] = bitcast 149 150 // Call to -initWith: with elided retain of consumed argument. 151 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 152 // CHECK-NEXT: [[ALLOC:%.*]] = bitcast 153 // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* [[ALLOC]], 154 155 // Initialization of return value, occuring within full-expression. 156 // Retain/release elided. 157 // CHECK-NEXT: bitcast 158 // CHECK-NEXT: [[INIT:%.*]] = bitcast 159 // CHECK-NEXT: [[RET:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[INIT]]) 160 161 // CHECK-NEXT: ret i8* [[RET]] 162 163 return [[Test3 alloc] initWith: 6]; 164} 165 166@interface Test5 { 167@public 168 id var; 169} 170@end 171 172// CHECK: define void @test5 173void test5(Test5 *x, id y) { 174 // Prologue. 175 // CHECK: [[X:%.*]] = alloca [[TEST5:%.*]]*, 176 // CHECK-NEXT: [[Y:%.*]] = alloca i8* 177 // CHECK-NEXT: bitcast [[TEST5]]* {{%.*}} to i8* 178 // CHECK-NEXT: call i8* @objc_retain 179 // CHECK-NEXT: [[PARMX:%.*]] = bitcast i8* {{%.*}} to [[TEST5]]* 180 // CHECK-NEXT: store [[TEST5]]* [[PARMX]], [[TEST5]]** [[X]] 181 // CHECK-NEXT: call i8* @objc_retain 182 // CHECK-NEXT: store 183 184 // CHECK-NEXT: load [[TEST5]]** [[X]] 185 // CHECK-NEXT: load i64* @"OBJC_IVAR_$_Test5.var" 186 // CHECK-NEXT: bitcast 187 // CHECK-NEXT: getelementptr 188 // CHECK-NEXT: [[VAR:%.*]] = bitcast 189 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[VAR]] 190 // CHECK-NEXT: store i8* null, i8** [[VAR]] 191 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind 192 x->var = 0; 193 194 // CHECK-NEXT: [[YVAL:%.*]] = load i8** [[Y]] 195 // CHECK-NEXT: load [[TEST5]]** [[X]] 196 // CHECK-NEXT: load i64* @"OBJC_IVAR_$_Test5.var" 197 // CHECK-NEXT: bitcast 198 // CHECK-NEXT: getelementptr 199 // CHECK-NEXT: [[VAR:%.*]] = bitcast 200 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[YVAL]]) nounwind 201 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[VAR]] 202 // CHECK-NEXT: store i8* [[T0]], i8** [[VAR]] 203 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind 204 x->var = y; 205 206 // Epilogue. 207 // CHECK-NEXT: [[TMP:%.*]] = load i8** [[Y]] 208 // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) nounwind 209 // CHECK-NEXT: [[T0:%.*]] = load [[TEST5]]** [[X]] 210 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST5]]* [[T0]] to i8* 211 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind 212 // CHECK-NEXT: ret void 213} 214 215id test6_helper(void) __attribute__((ns_returns_retained)); 216// CHECK: define void @test6() 217void test6() { 218 // CHECK: [[X:%.*]] = alloca i8* 219 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test6_helper() 220 // CHECK-NEXT: store i8* [[CALL]], i8** [[X]] 221 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 222 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 223 // CHECK-NEXT: ret void 224 id x = test6_helper(); 225} 226 227void test7_helper(id __attribute__((ns_consumed))); 228// CHECK: define void @test7() 229void test7() { 230 // CHECK: [[X:%.*]] = alloca i8* 231 // CHECK-NEXT: store i8* null, i8** [[X]] 232 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 233 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind 234 // CHECK-NEXT: call void @test7_helper(i8* [[T1]]) 235 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 236 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 237 // CHECK-NEXT: ret void 238 id x; 239 test7_helper(x); 240} 241 242id test8_helper(void) __attribute__((ns_returns_retained)); 243void test8() { 244 __unsafe_unretained id x = test8_helper(); 245 // CHECK: [[X:%.*]] = alloca i8* 246 // CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper() 247 // CHECK-NEXT: store i8* [[T0]], i8** [[X]] 248 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind 249 // CHECK-NOT: imprecise_release 250 // CHECK-NEXT: ret void 251} 252 253id test9_helper(void) __attribute__((ns_returns_retained)); 254void test9() { 255 id x __attribute__((objc_precise_lifetime)) = test9_helper(); 256 x = 0; 257 // CHECK: [[X:%.*]] = alloca i8* 258 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test9_helper() 259 // CHECK-NEXT: store i8* [[CALL]], i8** [[X]] 260 261 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 262 // CHECK-NEXT: store i8* null, i8** [[X]] 263 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 264 265 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 266 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind 267 // CHECK-NOT: clang.imprecise_release 268 269 // CHECK-NEXT: ret void 270} 271 272@interface Test10 273@property (retain) Test10 *me; 274@end 275void test10() { 276 Test10 *x; 277 id y = x.me.me; 278 279 // CHECK: define void @test10() 280 // CHECK: [[X:%.*]] = alloca [[TEST10:%.*]]*, align 281 // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 282 // CHECK-NEXT: store [[TEST10]]* null, [[TEST10]]** [[X]] 283 // CHECK-NEXT: load [[TEST10]]** [[X]], align 284 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" 285 // CHECK-NEXT: bitcast 286 // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 287 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* 288 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 289 // CHECK-NEXT: [[V:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* 290 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" 291 // CHECK-NEXT: bitcast 292 // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 293 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* 294 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 295 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* 296 // CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8* 297 // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 298 // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST10]]* [[V]] to i8* 299 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 300 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 301 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 302 // CHECK-NEXT: [[T0:%.*]] = load [[TEST10]]** [[X]] 303 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* 304 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 305 // CHECK-NEXT: ret void 306} 307 308void test11(id (*f)(void) __attribute__((ns_returns_retained))) { 309 // CHECK: define void @test11( 310 // CHECK: [[F:%.*]] = alloca i8* ()*, align 311 // CHECK-NEXT: [[X:%.*]] = alloca i8*, align 312 // CHECK-NEXT: store i8* ()* {{%.*}}, i8* ()** [[F]], align 313 // CHECK-NEXT: [[T0:%.*]] = load i8* ()** [[F]], align 314 // CHECK-NEXT: [[T1:%.*]] = call i8* [[T0]]() 315 // CHECK-NEXT: store i8* [[T1]], i8** [[X]], align 316 // CHECK-NEXT: [[T3:%.*]] = load i8** [[X]] 317 // CHECK-NEXT: call void @objc_release(i8* [[T3]]) nounwind, !clang.imprecise_release 318 // CHECK-NEXT: ret void 319 id x = f(); 320} 321 322void test12(void) { 323 extern id test12_helper(void); 324 325 // CHECK: define void @test12() 326 // CHECK: [[X:%.*]] = alloca i8*, align 327 // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 328 329 __weak id x = test12_helper(); 330 // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() 331 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 332 // CHECK-NEXT: call i8* @objc_initWeak(i8** [[X]], i8* [[T1]]) 333 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 334 335 x = test12_helper(); 336 // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() 337 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 338 // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[X]], i8* [[T1]]) 339 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 340 341 id y = x; 342 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[X]]) 343 // CHECK-NEXT: store i8* [[T2]], i8** [[Y]], align 344 345 // CHECK-NEXT: [[T4:%.*]] = load i8** [[Y]] 346 // CHECK-NEXT: call void @objc_release(i8* [[T4]]) nounwind, !clang.imprecise_release 347 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) 348 // CHECK-NEXT: ret void 349} 350 351// Indirect consuming calls. 352void test13(void) { 353 // CHECK: define void @test13() 354 // CHECK: [[X:%.*]] = alloca i8*, align 355 // CHECK-NEXT: store i8* null, i8** [[X]], align 356 id x; 357 358 typedef void fnty(id __attribute__((ns_consumed))); 359 extern fnty *test13_func; 360 // CHECK-NEXT: [[FN:%.*]] = load void (i8*)** @test13_func, align 361 // CHECK-NEXT: [[X_VAL:%.*]] = load i8** [[X]], align 362 // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) nounwind 363 // CHECK-NEXT: call void [[FN]](i8* [[X_TMP]]) 364 test13_func(x); 365 366 extern fnty ^test13_block; 367 // CHECK-NEXT: [[TMP:%.*]] = load void (i8*)** @test13_block, align 368 // CHECK-NEXT: [[BLOCK:%.*]] = bitcast void (i8*)* [[TMP]] to [[BLOCKTY:%.*]]* 369 // CHECK-NEXT: [[BLOCK_FN_PTR:%.*]] = getelementptr inbounds [[BLOCKTY]]* [[BLOCK]], i32 0, i32 3 370 // CHECK-NEXT: [[BLOCK_OPAQUE:%.*]] = bitcast [[BLOCKTY]]* [[BLOCK]] to i8* 371 // CHECK-NEXT: [[X_VAL:%.*]] = load i8** [[X]], align 372 // CHECK-NEXT: [[X_TMP:%.*]] = call i8* @objc_retain(i8* [[X_VAL]]) nounwind 373 // CHECK-NEXT: [[BLOCK_FN_TMP:%.*]] = load i8** [[BLOCK_FN_PTR]] 374 // CHECK-NEXT: [[BLOCK_FN:%.*]] = bitcast i8* [[BLOCK_FN_TMP]] to void (i8*, i8*)* 375 // CHECK-NEXT: call void [[BLOCK_FN]](i8* [[BLOCK_OPAQUE]], i8* [[X_TMP]]) 376 test13_block(x); 377 378 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 379 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind 380 // CHECK-NEXT: ret void 381} 382 383@interface Test16_super @end 384@interface Test16 : Test16_super { 385 id z; 386} 387@property (assign) int x; 388@property (retain) id y; 389- (void) dealloc; 390@end 391@implementation Test16 392@synthesize x; 393@synthesize y; 394- (void) dealloc { 395 // CHECK: define internal void @"\01-[Test16 dealloc]"( 396 // CHECK: [[SELF:%.*]] = alloca [[TEST16:%.*]]*, align 397 // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 398 // CHECK-NEXT: alloca 399 // CHECK-NEXT: store [[TEST16]]* {{%.*}}, [[TEST16]]** [[SELF]], align 400 // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 401 // CHECK-NEXT: [[BASE:%.*]] = load [[TEST16]]** [[SELF]] 402 403 // Call super. 404 // CHECK-NEXT: [[BASE2:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8* 405 // CHECK-NEXT: [[T0:%.*]] = getelementptr 406 // CHECK-NEXT: store i8* [[BASE2]], i8** [[T0]] 407 // CHECK-NEXT: load {{%.*}}** @"\01L_OBJC_CLASSLIST_SUP_REFS_$_ 408 // CHECK-NEXT: bitcast 409 // CHECK-NEXT: getelementptr 410 // CHECK-NEXT: store 411 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 412 // CHECK-NEXT: call void bitcast (i8* ({{.*}})* @objc_msgSendSuper2 to void ( 413 // CHECK-NEXT: ret void 414} 415 416// .cxx_destruct 417 // CHECK: define internal void @"\01-[Test16 .cxx_destruct]"( 418 // CHECK: [[SELF:%.*]] = alloca [[TEST16:%.*]]*, align 419 // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 420 // CHECK-NEXT: store [[TEST16]]* {{%.*}}, [[TEST16]]** [[SELF]], align 421 // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 422 // CHECK-NEXT: [[BASE:%.*]] = load [[TEST16]]** [[SELF]] 423 424 // Destroy y. 425 // CHECK-NEXT: [[Y_OFF:%.*]] = load i64* @"OBJC_IVAR_$_Test16.y" 426 // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8* 427 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[Y_OFF]] 428 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** 429 // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) nounwind 430 431 // Destroy z. 432 // CHECK-NEXT: [[Z_OFF:%.*]] = load i64* @"OBJC_IVAR_$_Test16.z" 433 // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST16]]* [[BASE]] to i8* 434 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[Z_OFF]] 435 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** 436 // CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) nounwind 437 438 // CHECK-NEXT: ret void 439 440@end 441 442// This shouldn't crash. 443@interface Test17A 444@property (assign) int x; 445@end 446@interface Test17B : Test17A 447@end 448@implementation Test17B 449- (int) x { return super.x + 1; } 450@end 451 452void test19() { 453 // CHECK: define void @test19() 454 // CHECK: [[X:%.*]] = alloca [5 x i8*], align 16 455 // CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8* 456 // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false) 457 id x[5]; 458 459 extern id test19_helper(void); 460 x[2] = test19_helper(); 461 462 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper() 463 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) nounwind 464 // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*]* [[X]], i32 0, i64 2 465 // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]] 466 // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] 467 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind 468 469 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x i8*]* [[X]], i32 0, i32 0 470 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 5 471 // CHECK-NEXT: br label 472 473 // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] 474 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1 475 // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]] 476 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release 477 // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] 478 // CHECK-NEXT: br i1 [[EQ]], 479 480 // CHECK: ret void 481} 482 483void test20(unsigned n) { 484 // CHECK: define void @test20 485 // CHECK: [[N:%.*]] = alloca i32, align 4 486 // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca i8* 487 // CHECK-NEXT: store i32 {{%.*}}, i32* [[N]], align 4 488 489 id x[n]; 490 491 // Capture the VLA size. 492 // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 493 // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64 494 495 // Save the stack pointer. 496 // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave() 497 // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]] 498 499 // Allocate the VLA. 500 // CHECK-NEXT: [[VLA:%.*]] = alloca i8*, i64 [[DIM]], align 16 501 502 // Zero-initialize. 503 // CHECK-NEXT: [[T0:%.*]] = bitcast i8** [[VLA]] to i8* 504 // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[DIM]], 8 505 // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[T1]], i32 8, i1 false) 506 507 // Destroy. 508 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[VLA]], i64 [[DIM]] 509 // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq i8** [[VLA]], [[END]] 510 // CHECK-NEXT: br i1 [[EMPTY]] 511 512 // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 513 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1 514 // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]] 515 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release 516 // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[VLA]] 517 // CHECK-NEXT: br i1 [[EQ]], 518 519 // CHECK: [[T0:%.*]] = load i8** [[SAVED_STACK]] 520 // CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]]) 521 // CHECK-NEXT: ret void 522} 523 524void test21(unsigned n) { 525 // CHECK: define void @test21 526 // CHECK: [[N:%.*]] = alloca i32, align 4 527 // CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca i8* 528 // CHECK-NEXT: store i32 {{%.*}}, i32* [[N]], align 4 529 530 id x[2][n][3]; 531 532 // Capture the VLA size. 533 // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 534 // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64 535 536 // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave() 537 // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]] 538 539 540 // Allocate the VLA. 541 // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]] 542 // CHECK-NEXT: [[VLA:%.*]] = alloca [3 x i8*], i64 [[T0]], align 16 543 544 // Zero-initialize. 545 // CHECK-NEXT: [[T0:%.*]] = bitcast [3 x i8*]* [[VLA]] to i8* 546 // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 2, [[DIM]] 547 // CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[T1]], 24 548 // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[T2]], i32 8, i1 false) 549 550 // Destroy. 551 // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]] 552 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [3 x i8*]* [[VLA]], i32 0, i32 0 553 // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[T0]], 3 554 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[T1]] 555 // CHECK-NEXT: [[EMPTY:%.*]] = icmp eq i8** [[BEGIN]], [[END]] 556 // CHECK-NEXT: br i1 [[EMPTY]] 557 558 // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 559 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1 560 // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]] 561 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release 562 // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] 563 // CHECK-NEXT: br i1 [[EQ]], 564 565 // CHECK: [[T0:%.*]] = load i8** [[SAVED_STACK]] 566 // CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]]) 567 // CHECK-NEXT: ret void 568} 569 570void test22(_Bool cond) { 571 id test22_helper(void) __attribute__((ns_returns_retained)); 572 573 // CHECK: define void @test22( 574 // CHECK: [[COND:%.*]] = alloca i8, 575 // CHECK-NEXT: [[X:%.*]] = alloca i8*, 576 // CHECK-NEXT: [[RELVAL:%.*]] = alloca i8* 577 // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1 578 // CHECK-NEXT: zext 579 // CHECK-NEXT: store 580 // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]] 581 // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1 582 // CHECK-NEXT: store i1 false, i1* [[RELCOND]] 583 // CHECK-NEXT: br i1 [[T1]], 584 // CHECK: br label 585 // CHECK: [[CALL:%.*]] = call i8* @test22_helper() 586 // CHECK-NEXT: store i8* [[CALL]], i8** [[RELVAL]] 587 // CHECK-NEXT: store i1 true, i1* [[RELCOND]] 588 // CHECK-NEXT: br label 589 // CHECK: [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ] 590 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind 591 // CHECK-NEXT: store i8* [[T1]], i8** [[X]], 592 // CHECK-NEXT: [[REL:%.*]] = load i1* [[RELCOND]] 593 // CHECK-NEXT: br i1 [[REL]], 594 // CHECK: [[T0:%.*]] = load i8** [[RELVAL]] 595 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind 596 // CHECK-NEXT: br label 597 // CHECK: [[T0:%.*]] = load i8** [[X]] 598 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind 599 // CHECK-NEXT: ret void 600 id x = (cond ? 0 : test22_helper()); 601} 602 603// rdar://problem/8922540 604// Note that we no longer emit .release_ivars flags. 605// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test23" = internal global [[RO_T:%.*]] { i32 134, 606@interface Test23 { id x; } @end 607@implementation Test23 @end 608 609// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test24" = internal global [[RO_T:%.*]] { i32 130, 610@interface Test24 {} @end 611@implementation Test24 @end 612 613// rdar://problem/8941012 614@interface Test26 { id x[4]; } @end 615@implementation Test26 @end 616// CHECK: define internal void @"\01-[Test26 .cxx_destruct]"( 617// CHECK: [[SELF:%.*]] = load [[TEST26:%.*]]** 618// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test26.x" 619// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST26]]* [[SELF]] to i8* 620// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]] 621// CHECK-NEXT: [[X:%.*]] = bitcast i8* [[T1]] to [4 x i8*]* 622// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x i8*]* [[X]], i32 0, i32 0 623// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 4 624// CHECK-NEXT: br label 625// CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 626// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1 627// CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) 628// CHECK-NEXT: [[ISDONE:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]] 629// CHECK-NEXT: br i1 [[ISDONE]], 630// CHECK: ret void 631 632// Check that 'init' retains self. 633@interface Test27 634- (id) init; 635@end 636@implementation Test27 637- (id) init { return self; } 638// CHECK: define internal i8* @"\01-[Test27 init]" 639// CHECK: [[SELF:%.*]] = alloca [[TEST27:%.*]]*, 640// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, 641// CHECK-NEXT: [[DEST:%.*]] = alloca i32 642// CHECK-NEXT: store [[TEST27]]* {{%.*}}, [[TEST27]]** [[SELF]] 643// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 644// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] 645// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* 646// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) 647// CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]] 648// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] 649// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* 650// CHECK-NEXT: call void @objc_release(i8* [[T1]]) 651// CHECK-NEXT: ret i8* [[RET]] 652 653@end 654 655// rdar://problem/8087194 656@interface Test28 657@property (copy) id prop; 658@end 659@implementation Test28 660@synthesize prop; 661@end 662// CHECK: define internal void @"\01-[Test28 .cxx_destruct]" 663// CHECK: [[SELF:%.*]] = load [[TEST28:%.*]]** 664// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test28.prop" 665// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST28]]* [[SELF]] to i8* 666// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]] 667// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** 668// CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) 669// CHECK-NEXT: ret void 670 671@interface Test29_super 672- (id) initWithAllocator: (id) allocator; 673@end 674@interface Test29 : Test29_super 675- (id) init; 676- (id) initWithAllocator: (id) allocator; 677@end 678@implementation Test29 679static id _test29_allocator = 0; 680- (id) init { 681// CHECK: define internal i8* @"\01-[Test29 init]"([[TEST29:%.*]]* {{%.*}}, 682// CHECK: [[SELF:%.*]] = alloca [[TEST29]]*, align 8 683// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8 684// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32 685// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]] 686// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 687 688// Evaluate arguments. Note that the send argument is evaluated 689// before the zeroing of self. 690// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]], align 8 691// CHECK-NEXT: [[T1:%.*]] = load i8** @_test29_allocator, align 8 692 693// Implicit null of 'self', i.e. direct transfer of ownership. 694// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]] 695 696// Actual message send. 697// CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 698// CHECK-NEXT: [[T3:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 699// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T3]], i8* [[T2]], i8* [[T1]]) 700 701// Implicit write of result back into 'self'. This is not supposed to 702// be detectable because we're supposed to ban accesses to the old 703// self value past the delegate init call. 704// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 705// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]] 706 707// Return statement. 708// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]] 709// CHECK-NEXT: [[CALL:%.*]] = bitcast 710// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind 711// CHECK-NEXT: store i32 1, i32* [[CLEANUP]] 712 713// Cleanup. 714// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 715// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 716// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 717 718// Return. 719// CHECK-NEXT: ret i8* [[RET]] 720 return [self initWithAllocator: _test29_allocator]; 721} 722- (id) initWithAllocator: (id) allocator { 723// CHECK: define internal i8* @"\01-[Test29 initWithAllocator:]"( 724// CHECK: [[SELF:%.*]] = alloca [[TEST29]]*, align 8 725// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8 726// CHECK-NEXT: [[ALLOCATOR:%.*]] = alloca i8*, align 8 727// CHECK-NEXT: alloca 728// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32 729// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]] 730// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 731// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) 732// CHECK-NEXT: store i8* [[T0]], i8** [[ALLOCATOR]] 733 734// Evaluate arguments. Note that the send argument is evaluated 735// before the zeroing of self. 736// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 737// CHECK-NEXT: [[T1:%.*]] = load i8** [[ALLOCATOR]], align 8 738 739// Implicit null of 'self', i.e. direct transfer of ownership. 740// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]] 741 742// Actual message send. 743// CHECK: [[CALL:%.*]] = call {{.*}} @objc_msgSendSuper2 744 745// Implicit write of result back into 'self'. This is not supposed to 746// be detectable because we're supposed to ban accesses to the old 747// self value past the delegate init call. 748// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 749// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]] 750 751// Assignment. 752// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 753// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 754// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind 755// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST29]]* 756// CHECK-NEXT: [[T4:%.*]] = load [[TEST29]]** [[SELF]], align 757// CHECK-NEXT: store [[TEST29]]* [[T3]], [[TEST29]]** [[SELF]], align 758// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST29]]* [[T4]] to i8* 759// CHECK-NEXT: call void @objc_release(i8* [[T5]]) 760 761// Return statement. 762// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 763// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 764// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind 765// CHECK-NEXT: store i32 1, i32* [[CLEANUP]] 766 767// Cleanup. 768// CHECK-NEXT: [[T0:%.*]] = load i8** [[ALLOCATOR]] 769// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release 770 771// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 772// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 773// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 774 775// Return. 776// CHECK-NEXT: ret i8* [[RET]] 777 self = [super initWithAllocator: allocator]; 778 return self; 779} 780@end 781 782typedef struct Test30_helper Test30_helper; 783@interface Test30 784- (id) init; 785- (Test30_helper*) initHelper; 786@end 787@implementation Test30 { 788char *helper; 789} 790- (id) init { 791// CHECK: define internal i8* @"\01-[Test30 init]"([[TEST30:%.*]]* {{%.*}}, 792// CHECK: [[RET:%.*]] = alloca [[TEST30]]* 793// CHECK-NEXT: alloca i8* 794// CHECK-NEXT: alloca i32 795// CHECK-NEXT: store [[TEST30]]* {{%.*}}, [[TEST30]]** [[SELF]] 796// CHECK-NEXT: store 797 798// Call. 799// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 800// CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 801// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 802// CHECK-NEXT: [[CALL:%.*]] = call [[TEST30_HELPER:%.*]]* bitcast {{.*}} @objc_msgSend {{.*}}(i8* [[T2]], i8* [[T1]]) 803 804// Assignment. 805// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST30_HELPER]]* [[CALL]] to i8* 806// CHECK-NEXT: [[T1:%.*]] = load [[TEST30]]** [[SELF]] 807// CHECK-NEXT: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Test30.helper" 808// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T1]] to i8* 809// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[IVAR]] 810// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 811// CHECK-NEXT#: [[T5:%.*]] = load i8** [[T4]] 812// CHECK-NEXT#: [[T6:%.*]] = call i8* @objc_retain(i8* [[T0]]) 813// CHECK-NEXT#: call void @objc_release(i8* [[T5]]) 814// CHECK-NEXT: store i8* [[T0]], i8** [[T4]] 815 816// Return. 817// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 818// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 819// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) 820// CHECK-NEXT: store i32 1 821 822// Cleanup. 823// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 824// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 825// CHECK-NEXT: call void @objc_release(i8* [[T1]]) 826 827// Epilogue. 828// CHECK-NEXT: ret i8* [[RET]] 829 self->helper = [self initHelper]; 830 return self; 831} 832- (Test30_helper*) initHelper { 833// CHECK: define internal [[TEST30_HELPER]]* @"\01-[Test30 initHelper]"( 834// CHECK: alloca 835// CHECK-NEXT: alloca 836// CHECK-NEXT: store 837// CHECK-NEXT: store 838// CHECK-NEXT: ret [[TEST30_HELPER]]* null 839 return 0; 840} 841 842@end 843 844__attribute__((ns_returns_retained)) id test32(void) { 845// CHECK: define i8* @test32() 846// CHECK: [[CALL:%.*]] = call i8* @test32_helper() 847// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 848// CHECK-NEXT: ret i8* [[T0]] 849 extern id test32_helper(void); 850 return test32_helper(); 851} 852 853@class Test33_a; 854@interface Test33 855- (void) give: (Test33_a **) x; 856- (void) take: (Test33_a **) x; 857- (void) giveStrong: (out __strong Test33_a **) x; 858- (void) takeStrong: (inout __strong Test33_a **) x; 859- (void) giveOut: (out Test33_a **) x; 860@end 861void test33(Test33 *ptr) { 862 Test33_a *a; 863 [ptr give: &a]; 864 [ptr take: &a]; 865 [ptr giveStrong: &a]; 866 [ptr takeStrong: &a]; 867 [ptr giveOut: &a]; 868 869 // CHECK: define void @test33([[TEST33:%.*]]* 870 // CHECK: [[PTR:%.*]] = alloca [[TEST33]]* 871 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]]* 872 // CHECK-NEXT: [[TEMP0:%.*]] = alloca [[A_T]]* 873 // CHECK-NEXT: [[TEMP1:%.*]] = alloca [[A_T]]* 874 // CHECK-NEXT: [[TEMP2:%.*]] = alloca [[A_T]]* 875 // CHECK-NEXT: bitcast 876 // CHECK-NEXT: objc_retain 877 // CHECK-NEXT: bitcast 878 // CHECK-NEXT: store 879 // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]] 880 881 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 882 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] 883 // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]] 884 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 885 // CHECK-NEXT: bitcast 886 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]]) 887 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP0]] 888 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 889 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 890 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 891 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 892 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 893 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 894 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 895 896 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 897 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] 898 // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]] 899 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 900 // CHECK-NEXT: bitcast 901 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]]) 902 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP1]] 903 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 904 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 905 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 906 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 907 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 908 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 909 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 910 911 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 912 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 913 // CHECK-NEXT: bitcast 914 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[A]]) 915 916 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 917 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 918 // CHECK-NEXT: bitcast 919 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[A]]) 920 921 // 'out' 922 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 923 // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[TEMP2]] 924 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 925 // CHECK-NEXT: bitcast 926 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP2]]) 927 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP2]] 928 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 929 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 930 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 931 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 932 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 933 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 934 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 935 936 // CHECK-NEXT: load 937 // CHECK-NEXT: bitcast 938 // CHECK-NEXT: objc_release 939 // CHECK-NEXT: load 940 // CHECK-NEXT: bitcast 941 // CHECK-NEXT: objc_release 942 // CHECK-NEXT: ret void 943} 944 945void test34(int cond) { 946 __strong id strong; 947 __weak id weak; 948 extern void test34_sink(id *); 949 test34_sink(cond ? &strong : 0); 950 test34_sink(cond ? &weak : 0); 951 952 // CHECK: define void @test34( 953 // CHECK: [[COND:%.*]] = alloca i32 954 // CHECK-NEXT: [[STRONG:%.*]] = alloca i8* 955 // CHECK-NEXT: [[WEAK:%.*]] = alloca i8* 956 // CHECK-NEXT: [[TEMP1:%.*]] = alloca i8* 957 // CHECK-NEXT: [[TEMP2:%.*]] = alloca i8* 958 // CHECK-NEXT: store i32 959 // CHECK-NEXT: store i8* null, i8** [[STRONG]] 960 // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null) 961 962 // CHECK-NEXT: [[T0:%.*]] = load i32* [[COND]] 963 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 964 // CHECK: [[ARG:%.*]] = phi i8** 965 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 966 // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]] 967 // CHECK-NEXT: br i1 [[T0]], 968 // CHECK: [[T0:%.*]] = load i8** [[ARG]] 969 // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]] 970 // CHECK-NEXT: br label 971 // CHECK: call void @test34_sink(i8** [[T1]]) 972 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 973 // CHECK-NEXT: br i1 [[T0]], 974 // CHECK: [[T0:%.*]] = load i8** [[TEMP1]] 975 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) 976 // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]] 977 // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] 978 // CHECK-NEXT: call void @objc_release(i8* [[T2]]) 979 // CHECK-NEXT: br label 980 981 // CHECK: [[T0:%.*]] = load i32* [[COND]] 982 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 983 // CHECK: [[ARG:%.*]] = phi i8** 984 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 985 // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]] 986 // CHECK-NEXT: br i1 [[T0]], 987 // CHECK: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[ARG]]) 988 // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]] 989 // CHECK-NEXT: br label 990 // CHECK: call void @test34_sink(i8** [[T1]]) 991 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 992 // CHECK-NEXT: br i1 [[T0]], 993 // CHECK: [[T0:%.*]] = load i8** [[TEMP2]] 994 // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]]) 995 // CHECK-NEXT: br label 996 997 // CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) 998 // CHECK: ret void 999} 1000 1001// CHECK: define void @test36 1002void test36(id x) { 1003 // CHECK: [[X:%.*]] = alloca i8* 1004 1005 // CHECK: call i8* @objc_retain 1006 // CHECK: call i8* @objc_retain 1007 // CHECK: call i8* @objc_retain 1008 id array[3] = { @"A", x, @"y" }; 1009 1010 // CHECK: [[T0:%.*]] = load i8** [[X]] 1011 // CHECK-NEXT: store i8* null, i8** [[X]] 1012 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1013 x = 0; 1014 1015 // CHECK: br label 1016 // CHECK: call void @objc_release 1017 // CHECK: br i1 1018 1019 // CHECK: call void @objc_release 1020 // CHECK-NEXT: ret void 1021} 1022 1023@class Test37; 1024void test37(void) { 1025 extern void test37_helper(id *); 1026 Test37 *var; 1027 test37_helper(&var); 1028 1029 // CHECK: define void @test37() 1030 // CHECK: [[VAR:%.*]] = alloca [[TEST37:%.*]]*, 1031 // CHECK-NEXT: [[TEMP:%.*]] = alloca i8* 1032 // CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]] 1033 1034 // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]] 1035 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* 1036 // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]] 1037 // CHECK-NEXT: call void @test37_helper(i8** [[TEMP]]) 1038 // CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] 1039 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]* 1040 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8* 1041 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) 1042 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]* 1043 // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]] 1044 // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] 1045 // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* 1046 // CHECK-NEXT: call void @objc_release(i8* [[T6]]) 1047 1048 // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]] 1049 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* 1050 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1051 // CHECK-NEXT: ret void 1052} 1053 1054@interface Test43 @end 1055@implementation Test43 1056- (id) test __attribute__((ns_returns_retained)) { 1057 extern id test43_produce(void); 1058 return test43_produce(); 1059 // CHECK: call i8* @test43_produce() 1060 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue( 1061 // CHECK-NEXT: ret 1062} 1063@end 1064 1065@interface Test45 1066@property (retain) id x; 1067@end 1068@implementation Test45 1069@synthesize x; 1070@end 1071// CHECK: define internal i8* @"\01-[Test45 x]"( 1072// CHECK: [[CALL:%.*]] = call i8* @objc_getProperty( 1073// CHECK-NEXT: ret i8* [[CALL]] 1074 1075// rdar://problem/9315552 1076void test46(__weak id *wp, __weak volatile id *wvp) { 1077 extern id test46_helper(void); 1078 1079 // TODO: this is sub-optimal, we should retain at the actual call site. 1080 1081 // CHECK: [[T0:%.*]] = call i8* @test46_helper() 1082 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1083 // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8 1084 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) 1085 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) 1086 // CHECK-NEXT: store i8* [[T4]], i8** 1087 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1088 id x = *wp = test46_helper(); 1089 1090 // CHECK: [[T0:%.*]] = call i8* @test46_helper() 1091 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1092 // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8 1093 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) 1094 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) 1095 // CHECK-NEXT: store i8* [[T4]], i8** 1096 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1097 id y = *wvp = test46_helper(); 1098} 1099 1100// rdar://problem/9378887 1101void test47(void) { 1102 extern id test47_helper(void); 1103 id x = x = test47_helper(); 1104 1105 // CHECK: define void @test47() 1106 // CHECK: [[X:%.*]] = alloca i8* 1107 // CHECK-NEXT: store i8* null, i8** [[X]] 1108 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper() 1109 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 1110 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 1111 // CHECK-NEXT: store i8* [[T0]], i8** [[X]] 1112 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1113 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T0]]) 1114 // CHECK-NEXT: [[T3:%.*]] = load i8** [[X]] 1115 // CHECK-NEXT: store i8* [[T2]], i8** [[X]] 1116 // CHECK-NEXT: call void @objc_release(i8* [[T3]]) 1117 // CHECK-NEXT: [[T4:%.*]] = load i8** [[X]] 1118 // CHECK-NEXT: call void @objc_release(i8* [[T4]]) 1119 // CHECK-NEXT: ret void 1120} 1121 1122void test48(void) { 1123 extern id test48_helper(void); 1124 __weak id x = x = test48_helper(); 1125 // CHECK: define void @test48() 1126 // CHECK: [[X:%.*]] = alloca i8* 1127 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_initWeak(i8** [[X]], i8* null) 1128 // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper() 1129 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1130 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T2]]) 1131 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T3]]) 1132 // CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1133 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) 1134 // CHECK-NEXT: ret void 1135} 1136 1137void test49(void) { 1138 extern id test49_helper(void); 1139 __autoreleasing id x = x = test49_helper(); 1140 // CHECK: define void @test49() 1141 // CHECK: [[X:%.*]] = alloca i8* 1142 // CHECK-NEXT: store i8* null, i8** [[X]] 1143 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper() 1144 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 1145 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autorelease(i8* [[T0]]) 1146 // CHECK-NEXT: store i8* [[T2]], i8** [[X]] 1147 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) 1148 // CHECK-NEXT: store i8* [[T3]], i8** [[X]] 1149 // CHECK-NEXT: ret void 1150} 1151 1152// rdar://9380136 1153id x(); 1154void test50(id y) { 1155 ({x();}); 1156// CHECK: [[T0:%.*]] = call i8* @objc_retain 1157// CHECK: call void @objc_release 1158} 1159 1160 1161// rdar://9400762 1162struct CGPoint { 1163 float x; 1164 float y; 1165}; 1166typedef struct CGPoint CGPoint; 1167 1168@interface Foo 1169@property (assign) CGPoint point; 1170@end 1171 1172@implementation Foo 1173@synthesize point; 1174@end 1175 1176// rdar://problem/9400398 1177id test52(void) { 1178 id test52_helper(int) __attribute__((ns_returns_retained)); 1179 return ({ int x = 5; test52_helper(x); }); 1180 1181// CHECK: define i8* @test52() 1182// CHECK: [[X:%.*]] = alloca i32 1183// CHECK-NEXT: store i32 5, i32* [[X]], 1184// CHECK-NEXT: [[T0:%.*]] = load i32* [[X]], 1185// CHECK-NEXT: [[T1:%.*]] = call i8* @test52_helper(i32 [[T0]]) 1186// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T1]]) 1187// CHECK-NEXT: ret i8* [[T2]] 1188} 1189 1190// rdar://problem/9400644 1191void test53(void) { 1192 id test53_helper(void); 1193 id x = ({ id y = test53_helper(); y; }); 1194 (void) x; 1195// CHECK: define void @test53() 1196// CHECK: [[X:%.*]] = alloca i8*, 1197// CHECK-NEXT: [[Y:%.*]] = alloca i8*, 1198// CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper() 1199// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1200// CHECK-NEXT: store i8* [[T1]], i8** [[Y]], 1201// CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]], 1202// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) 1203// CHECK-NEXT: [[T2:%.*]] = load i8** [[Y]] 1204// CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1205// CHECK-NEXT: store i8* [[T1]], i8** [[X]], 1206// CHECK-NEXT: load i8** [[X]], 1207// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 1208// CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1209// CHECK-NEXT: ret void 1210} 1211 1212// <rdar://problem/9758798> 1213// CHECK: define void @test54(i32 %first, ...) 1214void test54(int first, ...) { 1215 __builtin_va_list arglist; 1216 // CHECK: call void @llvm.va_start 1217 __builtin_va_start(arglist, first); 1218 // CHECK: call i8* @objc_retain 1219 id obj = __builtin_va_arg(arglist, id); 1220 // CHECK: call void @llvm.va_end 1221 __builtin_va_end(arglist); 1222 // CHECK: call void @objc_release 1223 // CHECK: ret void 1224} 1225 1226// PR10228 1227@interface Test55Base @end 1228@interface Test55 : Test55Base @end 1229@implementation Test55 (Category) 1230- (void) dealloc {} 1231@end 1232// CHECK: define internal void @"\01-[Test55(Category) dealloc]"( 1233// CHECK-NOT: ret 1234// CHECK: call void bitcast (i8* ({{%.*}}*, i8*, ...)* @objc_msgSendSuper2 to void ({{%.*}}*, i8*)*)( 1235 1236// rdar://problem/8024350 1237@protocol Test56Protocol 1238+ (id) make __attribute__((ns_returns_retained)); 1239@end 1240@interface Test56<Test56Protocol> @end 1241@implementation Test56 1242// CHECK: define internal i8* @"\01+[Test56 make]"( 1243+ (id) make { 1244 extern id test56_helper(void); 1245 // CHECK: [[T0:%.*]] = call i8* @test56_helper() 1246 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1247 // CHECK-NEXT: ret i8* [[T1]] 1248 return test56_helper(); 1249} 1250@end 1251void test56_test(void) { 1252 id x = [Test56 make]; 1253 // CHECK: define void @test56_test() 1254 // CHECK: [[X:%.*]] = alloca i8*, align 8 1255 // CHECK: [[T0:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)( 1256 // CHECK-NEXT: store i8* [[T0]], i8** [[X]] 1257 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 1258 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1259 // CHECK-NEXT: ret void 1260} 1261 1262// rdar://problem/9784964 1263@interface Test57 1264@property (nonatomic, strong) id strong; 1265@property (nonatomic, weak) id weak; 1266@property (nonatomic, unsafe_unretained) id unsafe; 1267@end 1268@implementation Test57 1269@synthesize strong, weak, unsafe; 1270@end 1271// CHECK: define internal i8* @"\01-[Test57 strong]"( 1272// CHECK: [[T0:%.*]] = load [[TEST57:%.*]]** {{%.*}} 1273// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.strong" 1274// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1275// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1276// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1277// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]] 1278// CHECK-NEXT: ret i8* [[T5]] 1279 1280// CHECK: define internal i8* @"\01-[Test57 weak]"( 1281// CHECK: [[T0:%.*]] = load [[TEST57]]** {{%.*}} 1282// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.weak" 1283// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1284// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1285// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1286// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]]) 1287// CHECK-NEXT: [[T6:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T5]]) 1288// CHECK-NEXT: ret i8* [[T6]] 1289 1290// CHECK: define internal i8* @"\01-[Test57 unsafe]"( 1291// CHECK: [[T0:%.*]] = load [[TEST57]]** {{%.*}} 1292// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.unsafe" 1293// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1294// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1295// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1296// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]] 1297// CHECK-NEXT: ret i8* [[T5]] 1298 1299// rdar://problem/9821110 1300@interface Test58 1301- (char*) interior __attribute__((objc_returns_inner_pointer)); 1302// Should we allow this on properties? 1303@end 1304extern Test58 *test58_helper(void); 1305 1306// CHECK: define void @test58a() 1307void test58a(void) { 1308 // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() 1309 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1310 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1311 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1312 // CHECK-NEXT: store [[TEST58]]* [[T3]] 1313 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1314 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1315 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) 1316 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1317 // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1318 // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8* 1319 // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast 1320 // CHECK-NEXT: store i8* [[T6]], i8** 1321 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1322 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1323 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 1324 // CHECK-NEXT: ret void 1325 Test58 *ptr = test58_helper(); 1326 char *c = [(ptr) interior]; 1327} 1328 1329// CHECK: define void @test58b() 1330void test58b(void) { 1331 // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() 1332 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1333 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1334 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1335 // CHECK-NEXT: store [[TEST58]]* [[T3]] 1336 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1337 // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1338 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1339 // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast 1340 // CHECK-NEXT: store i8* [[T3]], i8** 1341 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1342 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1343 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind 1344 // CHECK-NOT: clang.imprecise_release 1345 // CHECK-NEXT: ret void 1346 __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper(); 1347 char *c = [ptr interior]; 1348} 1349 1350// rdar://problem/9842343 1351void test59(void) { 1352 extern id test59_getlock(void); 1353 extern void test59_body(void); 1354 @synchronized (test59_getlock()) { 1355 test59_body(); 1356 } 1357 1358 // CHECK: define void @test59() 1359 // CHECK: [[T0:%.*]] = call i8* @test59_getlock() 1360 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1361 // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]]) 1362 // CHECK-NEXT: call void @test59_body() 1363 // CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]]) 1364 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1365 // CHECK-NEXT: ret void 1366} 1367 1368// Verify that we don't try to reclaim the result of performSelector. 1369// rdar://problem/9887545 1370@interface Test61 1371- (id) performSelector: (SEL) selector; 1372- (void) test61_void; 1373- (id) test61_id; 1374@end 1375void test61(void) { 1376 // CHECK: define void @test61() 1377 // CHECK: [[Y:%.*]] = alloca i8*, align 8 1378 1379 extern id test61_make(void); 1380 1381 // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() 1382 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1383 // CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1384 // CHECK-NEXT: [[T3:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1385 // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) 1386 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1387 [test61_make() performSelector: @selector(test61_void)]; 1388 1389 // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() 1390 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1391 // CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1392 // CHECK-NEXT: [[T3:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1393 // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) 1394 // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) 1395 // CHECK-NEXT: store i8* [[T5]], i8** [[Y]] 1396 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1397 id y = [test61_make() performSelector: @selector(test61_id)]; 1398 1399 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 1400 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1401 // CHECK-NEXT: ret void 1402} 1403 1404// rdar://problem/9891815 1405void test62(void) { 1406 // CHECK: define void @test62() 1407 // CHECK: [[I:%.*]] = alloca i32, align 4 1408 // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca i8* 1409 // CHECK-NEXT: [[CLEANUP_REQUIRED:%.*]] = alloca i1 1410 extern id test62_make(void); 1411 extern void test62_body(void); 1412 1413 // CHECK-NEXT: store i32 0, i32* [[I]], align 4 1414 // CHECK-NEXT: br label 1415 1416 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1417 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 20 1418 // CHECK-NEXT: br i1 [[T1]], 1419 1420 for (unsigned i = 0; i != 20; ++i) { 1421 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1422 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 1423 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]] 1424 // CHECK-NEXT: br i1 [[T1]], 1425 // CHECK: [[T0:%.*]] = call i8* @test62_make() 1426 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1427 // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]] 1428 // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]] 1429 // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null 1430 // CHECK-NEXT: br label 1431 // CHECK: [[COND:%.*]] = phi i1 [ false, {{%.*}} ], [ [[T2]], {{%.*}} ] 1432 // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_REQUIRED]] 1433 // CHECK-NEXT: br i1 [[T0]], 1434 // CHECK: [[T0:%.*]] = load i8** [[CLEANUP_VALUE]] 1435 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1436 // CHECK-NEXT: br label 1437 // CHECK: br i1 [[COND]] 1438 // CHECK: call void @test62_body() 1439 // CHECK-NEXT: br label 1440 // CHECK: br label 1441 if (i != 0 && test62_make() != 0) 1442 test62_body(); 1443 } 1444 1445 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1446 // CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], 1 1447 // CHECK-NEXT: store i32 [[T1]], i32* [[I]] 1448 // CHECK-NEXT: br label 1449 1450 // CHECK: ret void 1451} 1452 1453// rdar://9971982 1454@class NSString; 1455 1456@interface Person { 1457 NSString *name; 1458} 1459@property NSString *address; 1460@end 1461 1462@implementation Person 1463@synthesize address; 1464@end 1465// CHECK: call i8* @objc_getProperty 1466// CHECK: call void @objc_setProperty 1467 1468// Verify that we successfully parse and preserve this attribute in 1469// this position. 1470@interface Test66 1471- (void) consume: (id __attribute__((ns_consumed))) ptr; 1472@end 1473void test66(void) { 1474 extern Test66 *test66_receiver(void); 1475 extern id test66_arg(void); 1476 [test66_receiver() consume: test66_arg()]; 1477} 1478// CHECK: define void @test66() 1479// CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver() 1480// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8* 1481// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1482// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]* 1483// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg() 1484// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) 1485// CHECK-NEXT: [[T6:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES 1486// CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* 1487// CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null 1488// CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]] 1489// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]]) 1490// CHECK-NEXT: br label [[CONT:%.*]] 1491// CHECK: call void @objc_release(i8* [[T5]]) nounwind 1492// CHECK-NEXT: br label [[CONT:%.*]] 1493// CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* 1494// CHECK-NEXT: call void @objc_release(i8* [[T8]]) 1495// CHECK-NEXT: ret void 1496 1497// rdar://problem/9953540 1498Class test67_helper(void); 1499void test67(void) { 1500 Class cl = test67_helper(); 1501} 1502// CHECK: define void @test67() 1503// CHECK: [[CL:%.*]] = alloca i8*, align 8 1504// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() 1505// CHECK-NEXT: store i8* [[T0]], i8** [[CL]], align 8 1506// CHECK-NEXT: ret void 1507 1508Class test68_helper(void); 1509void test68(void) { 1510 __strong Class cl = test67_helper(); 1511} 1512// CHECK: define void @test68() 1513// CHECK: [[CL:%.*]] = alloca i8*, align 8 1514// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() 1515// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1516// CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8 1517// CHECK-NEXT: [[T2:%.*]] = load i8** [[CL]] 1518// CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1519// CHECK-NEXT: ret void 1520 1521// rdar://problem/10564852 1522@interface Test69 @end 1523@implementation Test69 1524- (id) foo { return self; } 1525@end 1526// CHECK: define internal i8* @"\01-[Test69 foo]"( 1527// CHECK: [[SELF:%.*]] = alloca [[TEST69:%.*]]*, align 8 1528// CHECK: [[T0:%.*]] = load [[TEST69]]** [[SELF]], align 8 1529// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST69]]* [[T0]] to i8* 1530// CHECK-NEXT: ret i8* [[T1]] 1531 1532// rdar://problem/10907547 1533void test70(id i) { 1534 // CHECK: define void @test70 1535 // CHECK: store i8* null, i8** 1536 // CHECK: store i8* null, i8** 1537 // CHECK: [[ID:%.*]] = call i8* @objc_retain(i8* 1538 // CHECK: store i8* [[ID]], i8** 1539 id x[3] = { 1540 [2] = i 1541 }; 1542} 1543