1*0a6a1f1dSLionel Sambuc// 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 2f4a2713aSLionel Sambuc 3f4a2713aSLionel Sambuc@interface A 4f4a2713aSLionel Sambuc@end 5f4a2713aSLionel Sambuc 6f4a2713aSLionel Sambucid getObject(); 7f4a2713aSLionel Sambucvoid callee(); 8f4a2713aSLionel Sambuc 9f4a2713aSLionel Sambuc// Lifetime extension for binding a reference to an rvalue 10f4a2713aSLionel Sambuc// CHECK-LABEL: define void @_Z5test0v() 11f4a2713aSLionel Sambucvoid test0() { 12f4a2713aSLionel Sambuc // CHECK: call i8* @_Z9getObjectv 13f4a2713aSLionel Sambuc // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 14f4a2713aSLionel Sambuc const __strong id &ref1 = getObject(); 15f4a2713aSLionel Sambuc // CHECK: call void @_Z6calleev 16f4a2713aSLionel Sambuc callee(); 17f4a2713aSLionel Sambuc // CHECK: call i8* @_Z9getObjectv 18f4a2713aSLionel Sambuc // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 19f4a2713aSLionel Sambuc // CHECK-NEXT: call i8* @objc_autorelease 20f4a2713aSLionel Sambuc const __autoreleasing id &ref2 = getObject(); 21f4a2713aSLionel Sambuc // CHECK: call void @_Z6calleev 22f4a2713aSLionel Sambuc callee(); 23f4a2713aSLionel Sambuc // CHECK: call void @objc_release 24f4a2713aSLionel Sambuc // CHECK-NEXT: ret 25f4a2713aSLionel Sambuc} 26f4a2713aSLionel Sambuc 27f4a2713aSLionel Sambuc// No lifetime extension when we're binding a reference to an lvalue. 28f4a2713aSLionel Sambuc// CHECK-LABEL: define void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_ 29f4a2713aSLionel Sambucvoid test1(__strong id &x, __weak id &y) { 30f4a2713aSLionel Sambuc // CHECK-NOT: release 31f4a2713aSLionel Sambuc const __strong id &ref1 = x; 32f4a2713aSLionel Sambuc const __autoreleasing id &ref2 = x; 33f4a2713aSLionel Sambuc const __weak id &ref3 = y; 34f4a2713aSLionel Sambuc // CHECK: ret void 35f4a2713aSLionel Sambuc} 36f4a2713aSLionel Sambuc 37f4a2713aSLionel Sambuctypedef __strong id strong_id; 38f4a2713aSLionel Sambuc 39f4a2713aSLionel Sambuc//CHECK: define void @_Z5test3v 40f4a2713aSLionel Sambucvoid test3() { 41f4a2713aSLionel Sambuc // CHECK: call i8* @objc_initWeak 42f4a2713aSLionel Sambuc // CHECK-NEXT: store i8** 43f4a2713aSLionel Sambuc const __weak id &ref = strong_id(); 44f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_Z6calleev() 45f4a2713aSLionel Sambuc callee(); 46f4a2713aSLionel Sambuc // CHECK-NEXT: call void @objc_destroyWeak 47f4a2713aSLionel Sambuc // CHECK-NEXT: ret void 48f4a2713aSLionel Sambuc} 49f4a2713aSLionel Sambuc 50f4a2713aSLionel Sambuc// CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object 51f4a2713aSLionel Sambucvoid test4(__strong id &x) { 52f4a2713aSLionel Sambuc // CHECK: call i8* @objc_retain 53f4a2713aSLionel Sambuc __strong A* const &ar = x; 54f4a2713aSLionel Sambuc // CHECK: store i32 17, i32* 55f4a2713aSLionel Sambuc int i = 17; 56f4a2713aSLionel Sambuc // CHECK: call void @objc_release( 57f4a2713aSLionel Sambuc // CHECK: ret void 58f4a2713aSLionel Sambuc} 59f4a2713aSLionel Sambuc 60f4a2713aSLionel Sambucvoid sink(__strong A* &&); 61f4a2713aSLionel Sambuc 62f4a2713aSLionel Sambuc// CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object 63f4a2713aSLionel Sambucvoid test5(__strong id &x) { 64f4a2713aSLionel Sambuc // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8 65f4a2713aSLionel Sambuc // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain( 66f4a2713aSLionel Sambuc // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]* 67f4a2713aSLionel Sambuc // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]] 68f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A 69f4a2713aSLionel Sambuc sink(x); 70f4a2713aSLionel Sambuc // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]** [[REFTMP]] 71f4a2713aSLionel Sambuc // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8* 72f4a2713aSLionel Sambuc // CHECK-NEXT: call void @objc_release 73f4a2713aSLionel Sambuc // CHECK-NEXT: store i32 17, i32 74f4a2713aSLionel Sambuc int i = 17; 75f4a2713aSLionel Sambuc // CHECK-NEXT: ret void 76f4a2713aSLionel Sambuc} 77f4a2713aSLionel Sambuc 78f4a2713aSLionel Sambuc// CHECK-LABEL: define internal void @__cxx_global_var_init( 79f4a2713aSLionel Sambuc// CHECK: call i8* @_Z9getObjectv 80f4a2713aSLionel Sambuc// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 81f4a2713aSLionel Sambucconst __strong id &global_ref = getObject(); 82f4a2713aSLionel Sambuc 83f4a2713aSLionel Sambuc// Note: we intentionally don't release the object. 84f4a2713aSLionel Sambuc 85