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} 13 14// CHECK: define i8* @test1(i8* 15id test1(id x) { 16 // CHECK: [[RET:%.*]] = alloca i8* 17 // CHECK-NEXT: [[X:%.*]] = alloca i8* 18 // CHECK-NEXT: [[Y:%.*]] = alloca i8* 19 // CHECK-NEXT: alloca i32 20 // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}}) 21 // CHECK-NEXT: store i8* [[PARM]], i8** [[X]] 22 // CHECK-NEXT: store i8* null, i8** [[Y]] 23 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 24 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) 25 // CHECK-NEXT: store i8* [[T1]], i8** [[RET]] 26 // CHECK-NEXT: store i32 27 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 28 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 29 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 30 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 31 // CHECK-NEXT: [[T0:%.*]] = load i8** [[RET]] 32 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T0]]) 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: [[RET:%.*]] = alloca i8*, 640// CHECK-NEXT: [[SELF:%.*]] = alloca [[TEST27:%.*]]*, 641// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, 642// CHECK-NEXT: [[DEST:%.*]] = alloca i32 643// CHECK-NEXT: store [[TEST27]]* {{%.*}}, [[TEST27]]** [[SELF]] 644// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 645// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] 646// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* 647// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 648// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] 649// CHECK-NEXT: [[T2:%.*]] = bitcast 650// CHECK-NEXT: store i8* [[T2]], i8** [[RET]] 651// CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]] 652// CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]] 653// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8* 654// CHECK-NEXT: call void @objc_release(i8* [[T1]]) 655// CHECK-NEXT: [[T0:%.*]] = load i8** [[RET]] 656// CHECK-NEXT: ret i8* [[T0]] 657 658@end 659 660// rdar://problem/8087194 661@interface Test28 662@property (copy) id prop; 663@end 664@implementation Test28 665@synthesize prop; 666@end 667// CHECK: define internal void @"\01-[Test28 .cxx_destruct]" 668// CHECK: [[SELF:%.*]] = load [[TEST28:%.*]]** 669// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test28.prop" 670// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST28]]* [[SELF]] to i8* 671// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]] 672// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** 673// CHECK-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null) 674// CHECK-NEXT: ret void 675 676@interface Test29_super 677- (id) initWithAllocator: (id) allocator; 678@end 679@interface Test29 : Test29_super 680- (id) init; 681- (id) initWithAllocator: (id) allocator; 682@end 683@implementation Test29 684static id _test29_allocator = 0; 685- (id) init { 686// CHECK: define internal i8* @"\01-[Test29 init]"([[TEST29:%.*]]* {{%.*}}, 687// CHECK: [[RET:%.*]] = alloca i8*, align 8 688// CHECK-NEXT: [[SELF:%.*]] = alloca [[TEST29]]*, align 8 689// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8 690// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32 691// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]] 692// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 693 694// Evaluate arguments. Note that the send argument is evaluated 695// before the zeroing of self. 696// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]], align 8 697// CHECK-NEXT: [[T1:%.*]] = load i8** @_test29_allocator, align 8 698 699// Implicit null of 'self', i.e. direct transfer of ownership. 700// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]] 701 702// Actual message send. 703// CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 704// CHECK-NEXT: [[T3:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 705// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T3]], i8* [[T2]], i8* [[T1]]) 706 707// Implicit write of result back into 'self'. This is not supposed to 708// be detectable because we're supposed to ban accesses to the old 709// self value past the delegate init call. 710// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 711// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]] 712 713// Return statement. 714// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]] 715// CHECK-NEXT: [[CALL:%.*]] = bitcast 716// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind 717// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] 718// CHECK-NEXT: [[T1:%.*]] = bitcast 719// CHECK-NEXT: store i8* [[T1]], i8** [[RET]] 720// CHECK-NEXT: store i32 1, i32* [[CLEANUP]] 721 722// Cleanup. 723// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 724// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 725// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 726 727// Return. 728// CHECK-NEXT: [[T0:%.*]] = load i8** [[RET]] 729// CHECK-NEXT: ret i8* [[T0]] 730 return [self initWithAllocator: _test29_allocator]; 731} 732- (id) initWithAllocator: (id) allocator { 733// CHECK: define internal i8* @"\01-[Test29 initWithAllocator:]"( 734// CHECK: [[RET:%.*]] = alloca i8*, align 8 735// CHECK-NEXT: [[SELF:%.*]] = alloca [[TEST29]]*, align 8 736// CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8 737// CHECK-NEXT: [[ALLOCATOR:%.*]] = alloca i8*, align 8 738// CHECK-NEXT: alloca 739// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32 740// CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]] 741// CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]] 742// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) 743// CHECK-NEXT: store i8* [[T0]], i8** [[ALLOCATOR]] 744 745// Evaluate arguments. Note that the send argument is evaluated 746// before the zeroing of self. 747// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 748// CHECK-NEXT: [[T1:%.*]] = load i8** [[ALLOCATOR]], align 8 749 750// Implicit null of 'self', i.e. direct transfer of ownership. 751// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]] 752 753// Actual message send. 754// CHECK: [[CALL:%.*]] = call {{.*}} @objc_msgSendSuper2 755 756// Implicit write of result back into 'self'. This is not supposed to 757// be detectable because we're supposed to ban accesses to the old 758// self value past the delegate init call. 759// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 760// CHECK-NEXT: store [[TEST29]]* [[T0]], [[TEST29]]** [[SELF]] 761 762// Assignment. 763// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CALL]] to [[TEST29]]* 764// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 765// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind 766// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST29]]* 767// CHECK-NEXT: [[T4:%.*]] = load [[TEST29]]** [[SELF]], align 768// CHECK-NEXT: store [[TEST29]]* [[T3]], [[TEST29]]** [[SELF]], align 769// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST29]]* [[T4]] to i8* 770// CHECK-NEXT: call void @objc_release(i8* [[T5]]) 771 772// Return statement. 773// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 774// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 775// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind 776// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] 777// CHECK-NEXT: [[T2:%.*]] = bitcast 778// CHECK-NEXT: store i8* [[T2]], i8** [[RET]] 779// CHECK-NEXT: store i32 1, i32* [[CLEANUP]] 780 781// Cleanup. 782// CHECK-NEXT: [[T0:%.*]] = load i8** [[ALLOCATOR]] 783// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release 784 785// CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]] 786// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8* 787// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release 788 789// Return. 790// CHECK-NEXT: [[T0:%.*]] = load i8** [[RET]] 791// CHECK-NEXT: ret i8* [[T0]] 792 self = [super initWithAllocator: allocator]; 793 return self; 794} 795@end 796 797typedef struct Test30_helper Test30_helper; 798@interface Test30 799- (id) init; 800- (Test30_helper*) initHelper; 801@end 802@implementation Test30 { 803char *helper; 804} 805- (id) init { 806// CHECK: define internal i8* @"\01-[Test30 init]"([[TEST30:%.*]]* {{%.*}}, 807// CHECK: [[RET:%.*]] = alloca i8* 808// CHECK-NEXT: [[SELF:%.*]] = alloca [[TEST30]]* 809// CHECK-NEXT: alloca i8* 810// CHECK-NEXT: alloca i32 811// CHECK-NEXT: store [[TEST30]]* {{%.*}}, [[TEST30]]** [[SELF]] 812// CHECK-NEXT: store 813 814// Call. 815// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 816// CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 817// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 818// CHECK-NEXT: [[CALL:%.*]] = call [[TEST30_HELPER:%.*]]* bitcast {{.*}} @objc_msgSend {{.*}}(i8* [[T2]], i8* [[T1]]) 819 820// Assignment. 821// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST30_HELPER]]* [[CALL]] to i8* 822// CHECK-NEXT: [[T1:%.*]] = load [[TEST30]]** [[SELF]] 823// CHECK-NEXT: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_Test30.helper" 824// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T1]] to i8* 825// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[IVAR]] 826// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 827// CHECK-NEXT#: [[T5:%.*]] = load i8** [[T4]] 828// CHECK-NEXT#: [[T6:%.*]] = call i8* @objc_retain(i8* [[T0]]) 829// CHECK-NEXT#: call void @objc_release(i8* [[T5]]) 830// CHECK-NEXT: store i8* [[T0]], i8** [[T4]] 831 832// Return. 833// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 834// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 835// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 836// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] 837// CHECK-NEXT: [[T2:%.*]] = bitcast 838// CHECK-NEXT: store i8* [[T2]], i8** [[RET]] 839// CHECK-NEXT: store i32 1 840 841// Cleanup. 842// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]] 843// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8* 844// CHECK-NEXT: call void @objc_release(i8* [[T1]]) 845 846// Epilogue. 847// CHECK-NEXT: [[T0:%.*]] = load i8** [[RET]] 848// CHECK-NEXT: ret i8* [[T0]] 849 self->helper = [self initHelper]; 850 return self; 851} 852- (Test30_helper*) initHelper { 853// CHECK: define internal [[TEST30_HELPER]]* @"\01-[Test30 initHelper]"( 854// CHECK: alloca 855// CHECK-NEXT: alloca 856// CHECK-NEXT: store 857// CHECK-NEXT: store 858// CHECK-NEXT: ret [[TEST30_HELPER]]* null 859 return 0; 860} 861 862@end 863 864__attribute__((ns_returns_retained)) id test32(void) { 865// CHECK: define i8* @test32() 866// CHECK: [[CALL:%.*]] = call i8* @test32_helper() 867// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 868// CHECK-NEXT: ret i8* [[T0]] 869 extern id test32_helper(void); 870 return test32_helper(); 871} 872 873@class Test33_a; 874@interface Test33 875- (void) give: (Test33_a **) x; 876- (void) take: (Test33_a **) x; 877- (void) giveStrong: (out __strong Test33_a **) x; 878- (void) takeStrong: (inout __strong Test33_a **) x; 879- (void) giveOut: (out Test33_a **) x; 880@end 881void test33(Test33 *ptr) { 882 Test33_a *a; 883 [ptr give: &a]; 884 [ptr take: &a]; 885 [ptr giveStrong: &a]; 886 [ptr takeStrong: &a]; 887 [ptr giveOut: &a]; 888 889 // CHECK: define void @test33([[TEST33:%.*]]* 890 // CHECK: [[PTR:%.*]] = alloca [[TEST33]]* 891 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]]* 892 // CHECK-NEXT: [[TEMP0:%.*]] = alloca [[A_T]]* 893 // CHECK-NEXT: [[TEMP1:%.*]] = alloca [[A_T]]* 894 // CHECK-NEXT: [[TEMP2:%.*]] = alloca [[A_T]]* 895 // CHECK-NEXT: bitcast 896 // CHECK-NEXT: objc_retain 897 // CHECK-NEXT: bitcast 898 // CHECK-NEXT: store 899 // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]] 900 901 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 902 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] 903 // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP0]] 904 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 905 // CHECK-NEXT: bitcast 906 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP0]]) 907 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP0]] 908 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 909 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 910 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 911 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 912 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 913 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 914 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 915 916 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 917 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[A]] 918 // CHECK-NEXT: store [[A_T]]* [[T0]], [[A_T]]** [[TEMP1]] 919 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 920 // CHECK-NEXT: bitcast 921 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP1]]) 922 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP1]] 923 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 924 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 925 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 926 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 927 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 928 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 929 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 930 931 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 932 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 933 // CHECK-NEXT: bitcast 934 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[A]]) 935 936 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 937 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 938 // CHECK-NEXT: bitcast 939 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[A]]) 940 941 // 'out' 942 // CHECK-NEXT: load [[TEST33]]** [[PTR]] 943 // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[TEMP2]] 944 // CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 945 // CHECK-NEXT: bitcast 946 // CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** [[TEMP2]]) 947 // CHECK-NEXT: [[T0:%.*]] = load [[A_T]]** [[TEMP2]] 948 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8* 949 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) 950 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A_T]]* 951 // CHECK-NEXT: [[T4:%.*]] = load [[A_T]]** [[A]] 952 // CHECK-NEXT: store [[A_T]]* [[T3]], [[A_T]]** [[A]] 953 // CHECK-NEXT: [[T5:%.*]] = bitcast [[A_T]]* [[T4]] to i8* 954 // CHECK-NEXT: call void @objc_release(i8* [[T5]]) 955 956 // CHECK-NEXT: load 957 // CHECK-NEXT: bitcast 958 // CHECK-NEXT: objc_release 959 // CHECK-NEXT: load 960 // CHECK-NEXT: bitcast 961 // CHECK-NEXT: objc_release 962 // CHECK-NEXT: ret void 963} 964 965void test34(int cond) { 966 __strong id strong; 967 __weak id weak; 968 extern void test34_sink(id *); 969 test34_sink(cond ? &strong : 0); 970 test34_sink(cond ? &weak : 0); 971 972 // CHECK: define void @test34( 973 // CHECK: [[COND:%.*]] = alloca i32 974 // CHECK-NEXT: [[STRONG:%.*]] = alloca i8* 975 // CHECK-NEXT: [[WEAK:%.*]] = alloca i8* 976 // CHECK-NEXT: [[TEMP1:%.*]] = alloca i8* 977 // CHECK-NEXT: [[TEMP2:%.*]] = alloca i8* 978 // CHECK-NEXT: store i32 979 // CHECK-NEXT: store i8* null, i8** [[STRONG]] 980 // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null) 981 982 // CHECK-NEXT: [[T0:%.*]] = load i32* [[COND]] 983 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 984 // CHECK: [[ARG:%.*]] = phi i8** 985 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 986 // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]] 987 // CHECK-NEXT: br i1 [[T0]], 988 // CHECK: [[T0:%.*]] = load i8** [[ARG]] 989 // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]] 990 // CHECK-NEXT: br label 991 // CHECK: call void @test34_sink(i8** [[T1]]) 992 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 993 // CHECK-NEXT: br i1 [[T0]], 994 // CHECK: [[T0:%.*]] = load i8** [[TEMP1]] 995 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) 996 // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]] 997 // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]] 998 // CHECK-NEXT: call void @objc_release(i8* [[T2]]) 999 // CHECK-NEXT: br label 1000 1001 // CHECK: [[T0:%.*]] = load i32* [[COND]] 1002 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 1003 // CHECK: [[ARG:%.*]] = phi i8** 1004 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 1005 // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]] 1006 // CHECK-NEXT: br i1 [[T0]], 1007 // CHECK: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[ARG]]) 1008 // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]] 1009 // CHECK-NEXT: br label 1010 // CHECK: call void @test34_sink(i8** [[T1]]) 1011 // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null 1012 // CHECK-NEXT: br i1 [[T0]], 1013 // CHECK: [[T0:%.*]] = load i8** [[TEMP2]] 1014 // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]]) 1015 // CHECK-NEXT: br label 1016 1017 // CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) 1018 // CHECK: ret void 1019} 1020 1021// CHECK: define void @test36 1022void test36(id x) { 1023 // CHECK: [[X:%.*]] = alloca i8* 1024 1025 // CHECK: call i8* @objc_retain 1026 // CHECK: call i8* @objc_retain 1027 // CHECK: call i8* @objc_retain 1028 id array[3] = { @"A", x, @"y" }; 1029 1030 // CHECK: [[T0:%.*]] = load i8** [[X]] 1031 // CHECK-NEXT: store i8* null, i8** [[X]] 1032 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1033 x = 0; 1034 1035 // CHECK: br label 1036 // CHECK: call void @objc_release 1037 // CHECK: br i1 1038 1039 // CHECK: call void @objc_release 1040 // CHECK-NEXT: ret void 1041} 1042 1043@class Test37; 1044void test37(void) { 1045 extern void test37_helper(id *); 1046 Test37 *var; 1047 test37_helper(&var); 1048 1049 // CHECK: define void @test37() 1050 // CHECK: [[VAR:%.*]] = alloca [[TEST37:%.*]]*, 1051 // CHECK-NEXT: [[TEMP:%.*]] = alloca i8* 1052 // CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]] 1053 1054 // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]] 1055 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* 1056 // CHECK-NEXT: store i8* [[T1]], i8** [[TEMP]] 1057 // CHECK-NEXT: call void @test37_helper(i8** [[TEMP]]) 1058 // CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] 1059 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST37]]* 1060 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST37]]* [[T1]] to i8* 1061 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) 1062 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST37]]* 1063 // CHECK-NEXT: [[T5:%.*]] = load [[TEST37]]** [[VAR]] 1064 // CHECK-NEXT: store [[TEST37]]* [[T4]], [[TEST37]]** [[VAR]] 1065 // CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST37]]* [[T5]] to i8* 1066 // CHECK-NEXT: call void @objc_release(i8* [[T6]]) 1067 1068 // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]** [[VAR]] 1069 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8* 1070 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1071 // CHECK-NEXT: ret void 1072} 1073 1074@interface Test43 @end 1075@implementation Test43 1076- (id) test __attribute__((ns_returns_retained)) { 1077 extern id test43_produce(void); 1078 return test43_produce(); 1079 // CHECK: call i8* @test43_produce() 1080 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue( 1081 // CHECK-NEXT: ret 1082} 1083@end 1084 1085@interface Test45 1086@property (retain) id x; 1087@end 1088@implementation Test45 1089@synthesize x; 1090@end 1091// CHECK: define internal i8* @"\01-[Test45 x]"( 1092// CHECK: [[CALL:%.*]] = call i8* @objc_getProperty( 1093// CHECK-NEXT: ret i8* [[CALL]] 1094 1095// rdar://problem/9315552 1096void test46(__weak id *wp, __weak volatile id *wvp) { 1097 extern id test46_helper(void); 1098 1099 // TODO: this is sub-optimal, we should retain at the actual call site. 1100 1101 // CHECK: [[T0:%.*]] = call i8* @test46_helper() 1102 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1103 // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8 1104 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) 1105 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) 1106 // CHECK-NEXT: store i8* [[T4]], i8** 1107 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1108 id x = *wp = test46_helper(); 1109 1110 // CHECK: [[T0:%.*]] = call i8* @test46_helper() 1111 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1112 // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8 1113 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]]) 1114 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]]) 1115 // CHECK-NEXT: store i8* [[T4]], i8** 1116 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1117 id y = *wvp = test46_helper(); 1118} 1119 1120// rdar://problem/9378887 1121void test47(void) { 1122 extern id test47_helper(void); 1123 id x = x = test47_helper(); 1124 1125 // CHECK: define void @test47() 1126 // CHECK: [[X:%.*]] = alloca i8* 1127 // CHECK-NEXT: store i8* null, i8** [[X]] 1128 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper() 1129 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 1130 // CHECK-NEXT: [[T1:%.*]] = load i8** [[X]] 1131 // CHECK-NEXT: store i8* [[T0]], i8** [[X]] 1132 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1133 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T0]]) 1134 // CHECK-NEXT: [[T3:%.*]] = load i8** [[X]] 1135 // CHECK-NEXT: store i8* [[T2]], i8** [[X]] 1136 // CHECK-NEXT: call void @objc_release(i8* [[T3]]) 1137 // CHECK-NEXT: [[T4:%.*]] = load i8** [[X]] 1138 // CHECK-NEXT: call void @objc_release(i8* [[T4]]) 1139 // CHECK-NEXT: ret void 1140} 1141 1142void test48(void) { 1143 extern id test48_helper(void); 1144 __weak id x = x = test48_helper(); 1145 // CHECK: define void @test48() 1146 // CHECK: [[X:%.*]] = alloca i8* 1147 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_initWeak(i8** [[X]], i8* null) 1148 // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper() 1149 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1150 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T2]]) 1151 // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T3]]) 1152 // CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1153 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]]) 1154 // CHECK-NEXT: ret void 1155} 1156 1157void test49(void) { 1158 extern id test49_helper(void); 1159 __autoreleasing id x = x = test49_helper(); 1160 // CHECK: define void @test49() 1161 // CHECK: [[X:%.*]] = alloca i8* 1162 // CHECK-NEXT: store i8* null, i8** [[X]] 1163 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper() 1164 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]]) 1165 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_autorelease(i8* [[T0]]) 1166 // CHECK-NEXT: store i8* [[T2]], i8** [[X]] 1167 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) 1168 // CHECK-NEXT: store i8* [[T3]], i8** [[X]] 1169 // CHECK-NEXT: ret void 1170} 1171 1172// rdar://9380136 1173id x(); 1174void test50(id y) { 1175 ({x();}); 1176// CHECK: [[T0:%.*]] = call i8* @objc_retain 1177// CHECK: call void @objc_release 1178} 1179 1180 1181// rdar://9400762 1182struct CGPoint { 1183 float x; 1184 float y; 1185}; 1186typedef struct CGPoint CGPoint; 1187 1188@interface Foo 1189@property (assign) CGPoint point; 1190@end 1191 1192@implementation Foo 1193@synthesize point; 1194@end 1195 1196// rdar://problem/9400398 1197id test52(void) { 1198 id test52_helper(int) __attribute__((ns_returns_retained)); 1199 return ({ int x = 5; test52_helper(x); }); 1200 1201// CHECK: define i8* @test52() 1202// CHECK: [[X:%.*]] = alloca i32 1203// CHECK-NEXT: store i32 5, i32* [[X]], 1204// CHECK-NEXT: [[T0:%.*]] = load i32* [[X]], 1205// CHECK-NEXT: [[T1:%.*]] = call i8* @test52_helper(i32 [[T0]]) 1206// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T1]]) 1207// CHECK-NEXT: ret i8* [[T2]] 1208} 1209 1210// rdar://problem/9400644 1211void test53(void) { 1212 id test53_helper(void); 1213 id x = ({ id y = test53_helper(); y; }); 1214 (void) x; 1215// CHECK: define void @test53() 1216// CHECK: [[X:%.*]] = alloca i8*, 1217// CHECK-NEXT: [[Y:%.*]] = alloca i8*, 1218// CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper() 1219// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1220// CHECK-NEXT: store i8* [[T1]], i8** [[Y]], 1221// CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]], 1222// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) 1223// CHECK-NEXT: [[T2:%.*]] = load i8** [[Y]] 1224// CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1225// CHECK-NEXT: store i8* [[T1]], i8** [[X]], 1226// CHECK-NEXT: load i8** [[X]], 1227// CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 1228// CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1229// CHECK-NEXT: ret void 1230} 1231 1232// <rdar://problem/9758798> 1233// CHECK: define void @test54(i32 %first, ...) 1234void test54(int first, ...) { 1235 __builtin_va_list arglist; 1236 // CHECK: call void @llvm.va_start 1237 __builtin_va_start(arglist, first); 1238 // CHECK: call i8* @objc_retain 1239 id obj = __builtin_va_arg(arglist, id); 1240 // CHECK: call void @llvm.va_end 1241 __builtin_va_end(arglist); 1242 // CHECK: call void @objc_release 1243 // CHECK: ret void 1244} 1245 1246// PR10228 1247@interface Test55Base @end 1248@interface Test55 : Test55Base @end 1249@implementation Test55 (Category) 1250- (void) dealloc {} 1251@end 1252// CHECK: define internal void @"\01-[Test55(Category) dealloc]"( 1253// CHECK-NOT: ret 1254// CHECK: call void bitcast (i8* ({{%.*}}*, i8*, ...)* @objc_msgSendSuper2 to void ({{%.*}}*, i8*)*)( 1255 1256// rdar://problem/8024350 1257@protocol Test56Protocol 1258+ (id) make __attribute__((ns_returns_retained)); 1259@end 1260@interface Test56<Test56Protocol> @end 1261@implementation Test56 1262// CHECK: define internal i8* @"\01+[Test56 make]"( 1263+ (id) make { 1264 extern id test56_helper(void); 1265 // CHECK: [[T0:%.*]] = call i8* @test56_helper() 1266 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1267 // CHECK-NEXT: ret i8* [[T1]] 1268 return test56_helper(); 1269} 1270@end 1271void test56_test(void) { 1272 id x = [Test56 make]; 1273 // CHECK: define void @test56_test() 1274 // CHECK: [[X:%.*]] = alloca i8*, align 8 1275 // CHECK: [[T0:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)( 1276 // CHECK-NEXT: store i8* [[T0]], i8** [[X]] 1277 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]] 1278 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1279 // CHECK-NEXT: ret void 1280} 1281 1282// rdar://problem/9784964 1283@interface Test57 1284@property (nonatomic, strong) id strong; 1285@property (nonatomic, weak) id weak; 1286@property (nonatomic, unsafe_unretained) id unsafe; 1287@end 1288@implementation Test57 1289@synthesize strong, weak, unsafe; 1290@end 1291// CHECK: define internal i8* @"\01-[Test57 strong]"( 1292// CHECK: [[T0:%.*]] = load [[TEST57:%.*]]** {{%.*}} 1293// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.strong" 1294// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1295// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1296// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1297// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]] 1298// CHECK-NEXT: ret i8* [[T5]] 1299 1300// CHECK: define internal i8* @"\01-[Test57 weak]"( 1301// CHECK: [[T0:%.*]] = load [[TEST57]]** {{%.*}} 1302// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.weak" 1303// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1304// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1305// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1306// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]]) 1307// CHECK-NEXT: [[T6:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T5]]) 1308// CHECK-NEXT: ret i8* [[T6]] 1309 1310// CHECK: define internal i8* @"\01-[Test57 unsafe]"( 1311// CHECK: [[T0:%.*]] = load [[TEST57]]** {{%.*}} 1312// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.unsafe" 1313// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8* 1314// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]] 1315// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8** 1316// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]] 1317// CHECK-NEXT: ret i8* [[T5]] 1318 1319// rdar://problem/9821110 1320@interface Test58 1321- (char*) interior __attribute__((objc_returns_inner_pointer)); 1322// Should we allow this on properties? 1323@end 1324extern Test58 *test58_helper(void); 1325 1326// CHECK: define void @test58a() 1327void test58a(void) { 1328 // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() 1329 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1330 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1331 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1332 // CHECK-NEXT: store [[TEST58]]* [[T3]] 1333 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1334 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1335 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) 1336 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1337 // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1338 // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8* 1339 // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast 1340 // CHECK-NEXT: store i8* [[T6]], 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, !clang.imprecise_release 1344 // CHECK-NEXT: ret void 1345 Test58 *ptr = test58_helper(); 1346 char *c = [(ptr) interior]; 1347} 1348 1349// CHECK: define void @test58b() 1350void test58b(void) { 1351 // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper() 1352 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1353 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1354 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]* 1355 // CHECK-NEXT: store [[TEST58]]* [[T3]] 1356 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1357 // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1358 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1359 // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast 1360 // CHECK-NEXT: store i8* [[T3]], i8** 1361 // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]** 1362 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8* 1363 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind 1364 // CHECK-NOT: clang.imprecise_release 1365 // CHECK-NEXT: ret void 1366 __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper(); 1367 char *c = [ptr interior]; 1368} 1369 1370// rdar://problem/9842343 1371void test59(void) { 1372 extern id test59_getlock(void); 1373 extern void test59_body(void); 1374 @synchronized (test59_getlock()) { 1375 test59_body(); 1376 } 1377 1378 // CHECK: define void @test59() 1379 // CHECK: [[T0:%.*]] = call i8* @test59_getlock() 1380 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1381 // CHECK-NEXT: call void @objc_sync_enter(i8* [[T1]]) 1382 // CHECK-NEXT: call void @test59_body() 1383 // CHECK-NEXT: call void @objc_sync_exit(i8* [[T1]]) 1384 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1385 // CHECK-NEXT: ret void 1386} 1387 1388// Verify that we don't try to reclaim the result of performSelector. 1389// rdar://problem/9887545 1390@interface Test61 1391- (id) performSelector: (SEL) selector; 1392- (void) test61_void; 1393- (id) test61_id; 1394@end 1395void test61(void) { 1396 // CHECK: define void @test61() 1397 // CHECK: [[Y:%.*]] = alloca i8*, align 8 1398 1399 extern id test61_make(void); 1400 1401 // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() 1402 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1403 // CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1404 // CHECK-NEXT: [[T3:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1405 // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) 1406 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1407 [test61_make() performSelector: @selector(test61_void)]; 1408 1409 // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() 1410 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1411 // CHECK-NEXT: [[T2:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1412 // CHECK-NEXT: [[T3:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ 1413 // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) 1414 // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) 1415 // CHECK-NEXT: store i8* [[T5]], i8** [[Y]] 1416 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) 1417 id y = [test61_make() performSelector: @selector(test61_id)]; 1418 1419 // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]] 1420 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1421 // CHECK-NEXT: ret void 1422} 1423 1424// rdar://problem/9891815 1425void test62(void) { 1426 // CHECK: define void @test62() 1427 // CHECK: [[I:%.*]] = alloca i32, align 4 1428 // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca i8* 1429 // CHECK-NEXT: [[CLEANUP_REQUIRED:%.*]] = alloca i1 1430 extern id test62_make(void); 1431 extern void test62_body(void); 1432 1433 // CHECK-NEXT: store i32 0, i32* [[I]], align 4 1434 // CHECK-NEXT: br label 1435 1436 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1437 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 20 1438 // CHECK-NEXT: br i1 [[T1]], 1439 1440 for (unsigned i = 0; i != 20; ++i) { 1441 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1442 // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 1443 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]] 1444 // CHECK-NEXT: br i1 [[T1]], 1445 // CHECK: [[T0:%.*]] = call i8* @test62_make() 1446 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1447 // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]] 1448 // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]] 1449 // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null 1450 // CHECK-NEXT: br label 1451 // CHECK: [[COND:%.*]] = phi i1 [ false, {{%.*}} ], [ [[T2]], {{%.*}} ] 1452 // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_REQUIRED]] 1453 // CHECK-NEXT: br i1 [[T0]], 1454 // CHECK: [[T0:%.*]] = load i8** [[CLEANUP_VALUE]] 1455 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) 1456 // CHECK-NEXT: br label 1457 // CHECK: br i1 [[COND]] 1458 // CHECK: call void @test62_body() 1459 // CHECK-NEXT: br label 1460 // CHECK: br label 1461 if (i != 0 && test62_make() != 0) 1462 test62_body(); 1463 } 1464 1465 // CHECK: [[T0:%.*]] = load i32* [[I]], align 4 1466 // CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], 1 1467 // CHECK-NEXT: store i32 [[T1]], i32* [[I]] 1468 // CHECK-NEXT: br label 1469 1470 // CHECK: ret void 1471} 1472 1473// rdar://9971982 1474@class NSString; 1475 1476@interface Person { 1477 NSString *name; 1478} 1479@property NSString *address; 1480@end 1481 1482@implementation Person 1483@synthesize address; 1484@end 1485// CHECK: call i8* @objc_getProperty 1486// CHECK: call void @objc_setProperty 1487 1488// Verify that we successfully parse and preserve this attribute in 1489// this position. 1490@interface Test66 1491- (void) consume: (id __attribute__((ns_consumed))) ptr; 1492@end 1493void test66(void) { 1494 extern Test66 *test66_receiver(void); 1495 extern id test66_arg(void); 1496 [test66_receiver() consume: test66_arg()]; 1497} 1498// CHECK: define void @test66() 1499// CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver() 1500// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8* 1501// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 1502// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]* 1503// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg() 1504// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) 1505// CHECK-NEXT: [[T6:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES 1506// CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* 1507// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]]) 1508// CHECK-NEXT: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* 1509// CHECK-NEXT: call void @objc_release(i8* [[T8]]) 1510// CHECK-NEXT: ret void 1511 1512// rdar://problem/9953540 1513Class test67_helper(void); 1514void test67(void) { 1515 Class cl = test67_helper(); 1516} 1517// CHECK: define void @test67() 1518// CHECK: [[CL:%.*]] = alloca i8*, align 8 1519// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() 1520// CHECK-NEXT: store i8* [[T0]], i8** [[CL]], align 8 1521// CHECK-NEXT: ret void 1522 1523Class test68_helper(void); 1524void test68(void) { 1525 __strong Class cl = test67_helper(); 1526} 1527// CHECK: define void @test68() 1528// CHECK: [[CL:%.*]] = alloca i8*, align 8 1529// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() 1530// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) 1531// CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8 1532// CHECK-NEXT: [[T2:%.*]] = load i8** [[CL]] 1533// CHECK-NEXT: call void @objc_release(i8* [[T2]]) 1534// CHECK-NEXT: ret void 1535