1*67e74705SXin Li// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li@interface A 4*67e74705SXin Li@end 5*67e74705SXin Li 6*67e74705SXin Liid getObject(); 7*67e74705SXin Livoid callee(); 8*67e74705SXin Li 9*67e74705SXin Li// Lifetime extension for binding a reference to an rvalue 10*67e74705SXin Li// CHECK-LABEL: define void @_Z5test0v() 11*67e74705SXin Livoid test0() { 12*67e74705SXin Li // CHECK: call i8* @_Z9getObjectv 13*67e74705SXin Li // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 14*67e74705SXin Li const __strong id &ref1 = getObject(); 15*67e74705SXin Li // CHECK: call void @_Z6calleev 16*67e74705SXin Li callee(); 17*67e74705SXin Li // CHECK: call i8* @_Z9getObjectv 18*67e74705SXin Li // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 19*67e74705SXin Li // CHECK-NEXT: call i8* @objc_autorelease 20*67e74705SXin Li const __autoreleasing id &ref2 = getObject(); 21*67e74705SXin Li // CHECK: call void @_Z6calleev 22*67e74705SXin Li callee(); 23*67e74705SXin Li // CHECK: call void @objc_release 24*67e74705SXin Li // CHECK-NEXT: ret 25*67e74705SXin Li} 26*67e74705SXin Li 27*67e74705SXin Li// No lifetime extension when we're binding a reference to an lvalue. 28*67e74705SXin Li// CHECK-LABEL: define void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_ 29*67e74705SXin Livoid test1(__strong id &x, __weak id &y) { 30*67e74705SXin Li // CHECK-NOT: release 31*67e74705SXin Li const __strong id &ref1 = x; 32*67e74705SXin Li const __autoreleasing id &ref2 = x; 33*67e74705SXin Li const __weak id &ref3 = y; 34*67e74705SXin Li // CHECK: ret void 35*67e74705SXin Li} 36*67e74705SXin Li 37*67e74705SXin Litypedef __strong id strong_id; 38*67e74705SXin Li 39*67e74705SXin Li//CHECK: define void @_Z5test3v 40*67e74705SXin Livoid test3() { 41*67e74705SXin Li // CHECK: [[REF:%.*]] = alloca i8**, align 8 42*67e74705SXin Li // CHECK: call i8* @objc_initWeak 43*67e74705SXin Li // CHECK-NEXT: store i8** 44*67e74705SXin Li const __weak id &ref = strong_id(); 45*67e74705SXin Li // CHECK-NEXT: call void @_Z6calleev() 46*67e74705SXin Li callee(); 47*67e74705SXin Li // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8* 48*67e74705SXin Li // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR]]) 49*67e74705SXin Li // CHECK-NEXT: call void @objc_destroyWeak 50*67e74705SXin Li // CHECK-NEXT: ret void 51*67e74705SXin Li} 52*67e74705SXin Li 53*67e74705SXin Li// CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object 54*67e74705SXin Livoid test4(__strong id &x) { 55*67e74705SXin Li // CHECK: call i8* @objc_retain 56*67e74705SXin Li __strong A* const &ar = x; 57*67e74705SXin Li // CHECK: store i32 17, i32* 58*67e74705SXin Li int i = 17; 59*67e74705SXin Li // CHECK: call void @objc_release( 60*67e74705SXin Li // CHECK: ret void 61*67e74705SXin Li} 62*67e74705SXin Li 63*67e74705SXin Livoid sink(__strong A* &&); 64*67e74705SXin Li 65*67e74705SXin Li// CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object 66*67e74705SXin Livoid test5(__strong id &x) { 67*67e74705SXin Li // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8 68*67e74705SXin Li // CHECK: [[I:%.*]] = alloca i32, align 4 69*67e74705SXin Li // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain( 70*67e74705SXin Li // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]* 71*67e74705SXin Li // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]] 72*67e74705SXin Li // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A 73*67e74705SXin Li sink(x); 74*67e74705SXin Li // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]] 75*67e74705SXin Li // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8* 76*67e74705SXin Li // CHECK-NEXT: call void @objc_release 77*67e74705SXin Li // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8* 78*67e74705SXin Li // CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[IPTR1]]) 79*67e74705SXin Li // CHECK-NEXT: store i32 17, i32 80*67e74705SXin Li int i = 17; 81*67e74705SXin Li // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8* 82*67e74705SXin Li // CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[IPTR2]]) 83*67e74705SXin Li // CHECK-NEXT: ret void 84*67e74705SXin Li} 85*67e74705SXin Li 86*67e74705SXin Li// CHECK-LABEL: define internal void @__cxx_global_var_init( 87*67e74705SXin Li// CHECK: call i8* @_Z9getObjectv 88*67e74705SXin Li// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 89*67e74705SXin Liconst __strong id &global_ref = getObject(); 90*67e74705SXin Li 91*67e74705SXin Li// Note: we intentionally don't release the object. 92*67e74705SXin Li 93