1f4a2713aSLionel Sambuc// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s 2f4a2713aSLionel Sambuc// rdar://10849570 3f4a2713aSLionel Sambuc 4f4a2713aSLionel Sambuc@interface NSObject @end 5f4a2713aSLionel Sambuc 6f4a2713aSLionel Sambuc@interface SomeClass : NSObject 7f4a2713aSLionel Sambuc- (id) init; 8f4a2713aSLionel Sambuc@end 9f4a2713aSLionel Sambuc 10f4a2713aSLionel Sambuc@implementation SomeClass 11f4a2713aSLionel Sambuc- (void)foo { 12f4a2713aSLionel Sambuc} 13f4a2713aSLionel Sambuc- (id) init { 14f4a2713aSLionel Sambuc return 0; 15f4a2713aSLionel Sambuc} 16f4a2713aSLionel Sambuc+ alloc { return 0; } 17f4a2713aSLionel Sambuc@end 18f4a2713aSLionel Sambuc 19f4a2713aSLionel Sambucint main (int argc, const char * argv[]) { 20f4a2713aSLionel Sambuc @autoreleasepool { 21f4a2713aSLionel Sambuc SomeClass *objPtr1 = [[SomeClass alloc] init]; 22f4a2713aSLionel Sambuc __weak SomeClass *weakRef = objPtr1; 23f4a2713aSLionel Sambuc 24f4a2713aSLionel Sambuc [weakRef foo]; 25f4a2713aSLionel Sambuc 26f4a2713aSLionel Sambuc objPtr1 = (void *)0; 27f4a2713aSLionel Sambuc return 0; 28f4a2713aSLionel Sambuc } 29f4a2713aSLionel Sambuc} 30f4a2713aSLionel Sambuc 31f4a2713aSLionel Sambuc// CHECK: [[SIXTEEN:%.*]] = call i8* @objc_loadWeakRetained(i8** {{%.*}}) 32f4a2713aSLionel Sambuc// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}} 33*0a6a1f1dSLionel Sambuc// CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8** @OBJC_SELECTOR_REFERENCES_6 34f4a2713aSLionel Sambuc// CHECK-NEXT: [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8* 35f4a2713aSLionel Sambuc// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 36f4a2713aSLionel Sambuc// CHECK-NEXT: [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8* 37f4a2713aSLionel Sambuc// CHECK-NEXT: call void @objc_release(i8* [[TWENTY]]) 38f4a2713aSLionel Sambuc 39f4a2713aSLionel Sambucvoid test1(int cond) { 40f4a2713aSLionel Sambuc extern void test34_sink(id *); 41f4a2713aSLionel Sambuc __weak id weak; 42f4a2713aSLionel Sambuc test34_sink(cond ? &weak : 0); 43f4a2713aSLionel Sambuc} 44f4a2713aSLionel Sambuc 45f4a2713aSLionel Sambuc// CHECK-LABEL: define void @test1( 46f4a2713aSLionel Sambuc// CHECK: [[CONDADDR:%.*]] = alloca i32 47f4a2713aSLionel Sambuc// CHECK-NEXT: [[WEAK:%.*]] = alloca i8* 48f4a2713aSLionel Sambuc// CHECK-NEXT: [[INCRTEMP:%.*]] = alloca i8* 49f4a2713aSLionel Sambuc// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8* 50f4a2713aSLionel Sambuc// CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1 51f4a2713aSLionel Sambuc// CHECK-NEXT: store i32 52f4a2713aSLionel Sambuc// CHECK-NEXT: store i8* null, i8** [[WEAK]] 53f4a2713aSLionel Sambuc// CHECK: [[COND1:%.*]] = phi i8** 54f4a2713aSLionel Sambuc// CHECK-NEXT: [[ICRISNULL:%.*]] = icmp eq i8** [[COND1]], null 55f4a2713aSLionel Sambuc// CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], i8** null, i8** [[INCRTEMP]] 56f4a2713aSLionel Sambuc// CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]] 57f4a2713aSLionel Sambuc// CHECK-NEXT: br i1 [[ICRISNULL]], label [[ICRCONT:%.*]], label [[ICRCOPY:%.*]] 58f4a2713aSLionel Sambuc// CHECK: [[ONE:%.*]] = call i8* @objc_loadWeakRetained( 59f4a2713aSLionel Sambuc// CHECK-NEXT: store i8* [[ONE]], i8** [[CONDCLEANUPSAVE]] 60f4a2713aSLionel Sambuc// CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]] 61f4a2713aSLionel Sambuc// CHECK-NEXT: store i8* [[ONE]], i8** [[INCRTEMP]] 62f4a2713aSLionel Sambuc// CHECK-NEXT: br label 63f4a2713aSLionel Sambuc 64f4a2713aSLionel Sambuc// CHECK: call void @test34_sink( 65f4a2713aSLionel Sambuc// CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq i8** [[COND1]], null 66f4a2713aSLionel Sambuc// CHECK-NEXT: br i1 [[ICRISNULL1]], label [[ICRDONE:%.*]], label [[ICRWRITEBACK:%.*]] 67f4a2713aSLionel Sambuc// CHECK: [[TWO:%.*]] = load i8** [[INCRTEMP]] 68f4a2713aSLionel Sambuc// CHECK-NEXT: [[THREE:%.*]] = call i8* @objc_storeWeak( 69f4a2713aSLionel Sambuc// CHECK-NEXT br label [[ICRDONE]] 70f4a2713aSLionel Sambuc// CHECK: [[CLEANUPISACTIVE:%.*]] = load i1* [[CONDCLEANUP]] 71f4a2713aSLionel Sambuc// CHECK-NEXT: br i1 [[CLEANUPISACTIVE]], label [[CLEASNUPACTION:%.*]], label [[CLEANUPDONE:%.*]] 72f4a2713aSLionel Sambuc 73f4a2713aSLionel Sambuc// CHECK: [[FOUR:%.*]] = load i8** [[CONDCLEANUPSAVE]] 74f4a2713aSLionel Sambuc// CHECK-NEXT: call void @objc_release(i8* [[FOUR]]) 75f4a2713aSLionel Sambuc// CHECK-NEXT: br label 76f4a2713aSLionel Sambuc// CHECK: call void @objc_destroyWeak(i8** [[WEAK]]) 77f4a2713aSLionel Sambuc// CHECK-NEXT: ret void 78