diff options
| author | John McCall <rjmccall@apple.com> | 2011-07-22 08:53:00 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-07-22 08:53:00 +0000 |
| commit | cf1667022fec6f94a3178d92cb8a719e971d63bc (patch) | |
| tree | 9e430e576576a723f1a0e0687d700a98678a4e7a /clang/test/CodeGenObjC | |
| parent | 969c32acb2dc026c5efc5f43ccfb01c1f2df7325 (diff) | |
| download | bcm5719-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.m | 50 |
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]; +} |

