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