150
|
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
|
|
6 id getObject();
|
|
7 void callee();
|
|
8
|
|
9 // Lifetime extension for binding a reference to an rvalue
|
221
|
10 // CHECK-LABEL: define{{.*}} void @_Z5test0v()
|
150
|
11 void test0() {
|
|
12 // CHECK: call i8* @_Z9getObjectv
|
|
13 // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
|
14 const __strong id &ref1 = getObject();
|
|
15 // CHECK: call void @_Z6calleev
|
|
16 callee();
|
|
17 // CHECK: call i8* @_Z9getObjectv
|
|
18 // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
|
19 // CHECK-NEXT: call i8* @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.
|
221
|
28 // CHECK-LABEL: define{{.*}} void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_
|
150
|
29 void 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
|
|
37 typedef __strong id strong_id;
|
|
38
|
221
|
39 //CHECK: define{{.*}} void @_Z5test3v
|
150
|
40 void test3() {
|
|
41 // CHECK: [[REF:%.*]] = alloca i8**, align 8
|
|
42 // CHECK: call i8* @llvm.objc.initWeak
|
|
43 // CHECK-NEXT: store i8**
|
|
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: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8*
|
|
49 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR]])
|
|
50 // CHECK-NEXT: ret void
|
|
51 }
|
|
52
|
221
|
53 // CHECK-LABEL: define{{.*}} void @_Z5test4RU8__strongP11objc_object
|
150
|
54 void test4(__strong id &x) {
|
|
55 // CHECK: call i8* @llvm.objc.retain
|
|
56 __strong A* const &ar = x;
|
|
57 // CHECK: store i32 17, i32*
|
|
58 int i = 17;
|
|
59 // CHECK: call void @llvm.objc.release(
|
|
60 // CHECK: ret void
|
|
61 }
|
|
62
|
|
63 void sink(__strong A* &&);
|
|
64
|
221
|
65 // CHECK-LABEL: define{{.*}} void @_Z5test5RU8__strongP11objc_object
|
150
|
66 void test5(__strong id &x) {
|
|
67 // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8
|
|
68 // CHECK: [[I:%.*]] = alloca i32, align 4
|
|
69 // CHECK: [[OBJ_ID:%.*]] = call i8* @llvm.objc.retain(
|
|
70 // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
|
|
71 // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
|
|
72 // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
|
|
73 sink(x);
|
|
74 // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]]
|
|
75 // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
|
|
76 // CHECK-NEXT: call void @llvm.objc.release
|
|
77 // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*
|
|
78 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[IPTR1]])
|
|
79 // CHECK-NEXT: store i32 17, i32
|
|
80 int i = 17;
|
|
81 // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*
|
|
82 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[IPTR2]])
|
|
83 // CHECK-NEXT: ret void
|
|
84 }
|
|
85
|
|
86 // CHECK-LABEL: define internal void @__cxx_global_var_init(
|
|
87 // CHECK: call i8* @_Z9getObjectv
|
|
88 // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
|
89 const __strong id &global_ref = getObject();
|
|
90
|
|
91 // Note: we intentionally don't release the object.
|
|
92
|