1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
3 #define PRECISE_LIFETIME __attribute__((objc_precise_lifetime))
5 id test0_helper(void) __attribute__((ns_returns_retained));
7 PRECISE_LIFETIME id x = test0_helper();
9 // CHECK: [[X:%.*]] = alloca i8*
10 // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
11 // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])
12 // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()
13 // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]
15 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
16 // CHECK-NEXT: store i8* null, i8** [[X]]
17 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
18 // CHECK-NOT: clang.imprecise_release
20 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
21 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]
22 // CHECK-NOT: clang.imprecise_release
24 // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*
25 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])
26 // CHECK-NEXT: ret void
29 // rdar://problem/9821110
31 - (char*) interior __attribute__((objc_returns_inner_pointer));
32 // Should we allow this on properties? Yes! see // rdar://14990439
33 @property (nonatomic, readonly) char * PropertyReturnsInnerPointer __attribute__((objc_returns_inner_pointer));
35 extern Test1 *test1_helper(void);
37 // CHECK-LABEL: define void @test1a()
39 // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
40 // CHECK: [[C:%.*]] = alloca i8*, align 8
41 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
42 // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
43 // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
44 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
45 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
46 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
47 // CHECK-NEXT: store [[TEST1]]* [[T3]]
48 // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
49 // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
50 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
51 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
52 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
53 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
54 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
55 // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
56 // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
57 // CHECK-NEXT: store i8* [[T6]], i8**
58 // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
59 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
60 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
61 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
62 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
63 // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
64 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
65 // CHECK-NEXT: ret void
66 Test1 *ptr = test1_helper();
67 char *c = [(ptr) interior];
70 // CHECK-LABEL: define void @test1b()
72 // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
73 // CHECK: [[C:%.*]] = alloca i8*, align 8
74 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
75 // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
76 // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
77 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
78 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
79 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
80 // CHECK-NEXT: store [[TEST1]]* [[T3]]
81 // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
82 // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])
83 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
84 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
85 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
86 // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
87 // CHECK-NEXT: store i8* [[T3]], i8**
88 // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
89 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])
90 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
91 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
92 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]
93 // CHECK-NOT: clang.imprecise_release
94 // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
95 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
96 // CHECK-NEXT: ret void
97 __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();
98 char *c = [ptr interior];
102 // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
103 // CHECK: [[PC:%.*]] = alloca i8*, align 8
104 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
105 // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
106 // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
107 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
108 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
109 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
110 // CHECK-NEXT: store [[TEST1]]* [[T3]]
111 // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
112 // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
113 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
114 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
115 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
116 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
117 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
118 // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
119 // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
120 // CHECK-NEXT: store i8* [[T6]], i8**
121 // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
122 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
123 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
124 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
125 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
126 // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
127 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
128 // CHECK-NEXT: ret void
129 Test1 *ptr = test1_helper();
130 char *pc = ptr.PropertyReturnsInnerPointer;
134 // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8
135 // CHECK: [[PC:%.*]] = alloca i8*, align 8
136 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
137 // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])
138 // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
139 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
140 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
141 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
142 // CHECK-NEXT: store [[TEST1]]* [[T3]]
143 // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
144 // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])
145 // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
146 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
147 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease
148 // CHECK-NEXT: [[SIX:%.*]] = bitcast i8* [[T3]] to [[TEST1]]*
149 // CHECK-NEXT: [[SEVEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
150 // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[SIX]] to i8*
151 // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]])
152 // CHECK-NEXT: store i8* [[CALL1]], i8**
153 // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
154 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])
155 // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**
156 // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*
157 // CHECK-NEXT: call void @objc_release(i8* [[TEN]])
158 // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
159 // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])
160 // CHECK-NEXT: ret void
161 __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();
162 char *pc = ptr.PropertyReturnsInnerPointer;
170 // CHECK-LABEL: define void @test2(
171 void test2(Test2 *x) {
173 // CHECK: [[X:%.*]] = alloca [[TEST2:%.*]]*
174 // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
175 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]
176 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST2]]*
177 // CHECK-NEXT: store [[TEST2]]* [[T2]], [[TEST2]]** [[X]],
179 // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]],
180 // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* @"OBJC_IVAR_$_Test2.ivar"
181 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
182 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 [[OFFSET]]
183 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
184 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]],
185 // CHECK-NEXT: store i8* null, i8** [[T3]],
186 // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]]
187 // CHECK-NOT: imprecise
189 // CHECK-NEXT: [[T0:%.*]] = load [[TEST2]]*, [[TEST2]]** [[X]]
190 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
191 // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release
193 // CHECK-NEXT: ret void
196 // CHECK-LABEL: define void @test3(i8*
197 void test3(PRECISE_LIFETIME id x) {
198 // CHECK: [[X:%.*]] = alloca i8*,
199 // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}}) [[NUW]]
200 // CHECK-NEXT: store i8* [[T0]], i8** [[X]],
202 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
203 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]
204 // CHECK-NOT: imprecise_release
206 // CHECK-NEXT: ret void
209 // CHECK: attributes [[NUW]] = { nounwind }