aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenObjC/arc.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenObjC/arc.m')
-rw-r--r--test/CodeGenObjC/arc.m50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index 8d74ab2a6a..918cbcbb3b 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -1616,3 +1616,53 @@ void test56_test(void) {
// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]]
// CHECK-NEXT: ret i8* [[T5]]
+// rdar://problem/9821110
+@interface Test58
+- (char*) interior __attribute__((objc_returns_inner_pointer));
+// Should we allow this on properties?
+@end
+extern Test58 *test58_helper(void);
+
+// CHECK: define void @test58a()
+void test58a(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
+ // CHECK-NEXT: store [[TEST58]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
+ // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST58]]* [[T3]] to i8*
+ // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T6]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind, !clang.imprecise_release
+ // CHECK-NEXT: ret void
+ Test58 *ptr = test58_helper();
+ char *c = [(ptr) interior];
+}
+
+// CHECK: define void @test58b()
+void test58b(void) {
+ // CHECK: [[T0:%.*]] = call [[TEST58:%.*]]* @test58_helper()
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST58]]*
+ // CHECK-NEXT: store [[TEST58]]* [[T3]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
+ // CHECK-NEXT: [[T1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
+ // CHECK-NEXT: store i8* [[T3]], i8**
+ // CHECK-NEXT: [[T0:%.*]] = load [[TEST58]]**
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST58]]* [[T0]] to i8*
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+ // CHECK-NOT: clang.imprecise_release
+ // CHECK-NEXT: ret void
+ __attribute__((objc_precise_lifetime)) Test58 *ptr = test58_helper();
+ char *c = [ptr interior];
+}