summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenObjC
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-22 08:53:00 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-22 08:53:00 +0000
commitcf1667022fec6f94a3178d92cb8a719e971d63bc (patch)
tree9e430e576576a723f1a0e0687d700a98678a4e7a /clang/test/CodeGenObjC
parent969c32acb2dc026c5efc5f43ccfb01c1f2df7325 (diff)
downloadbcm5719-llvm-cf1667022fec6f94a3178d92cb8a719e971d63bc.tar.gz
bcm5719-llvm-cf1667022fec6f94a3178d92cb8a719e971d63bc.zip
Document the existing objc_precise_lifetime attribute.
Introduce and document a new objc_returns_inner_pointer attribute, and consume it by performing a retain+autorelease on message receivers when they're not immediately loaded from an object with precise lifetime. llvm-svn: 135764
Diffstat (limited to 'clang/test/CodeGenObjC')
-rw-r--r--clang/test/CodeGenObjC/arc.m50
1 files changed, 50 insertions, 0 deletions
diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m
index 8d74ab2a6a9..918cbcbb3b5 100644
--- a/clang/test/CodeGenObjC/arc.m
+++ b/clang/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];
+}
OpenPOWER on IntegriCloud