summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenObjC/arc.m
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-08-03 22:24:24 +0000
committerJohn McCall <rjmccall@apple.com>2011-08-03 22:24:24 +0000
commit9c8e1c9401fac74a10ccfcfe174214be91dbb772 (patch)
treeac9e6894a920af3c612be98c5640783b627b1b81 /clang/test/CodeGenObjC/arc.m
parent2d3138c112cf2f15ab1c131f5f0af0a1cbe76391 (diff)
downloadbcm5719-llvm-9c8e1c9401fac74a10ccfcfe174214be91dbb772.tar.gz
bcm5719-llvm-9c8e1c9401fac74a10ccfcfe174214be91dbb772.zip
Use the general conditional-cleanup framework instead of rolling our
own, incorrectly, for releasing objects at the end of a full-expression. llvm-svn: 136823
Diffstat (limited to 'clang/test/CodeGenObjC/arc.m')
-rw-r--r--clang/test/CodeGenObjC/arc.m55
1 files changed, 52 insertions, 3 deletions
diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m
index 4592710a3d0..7883b0ebaf7 100644
--- a/clang/test/CodeGenObjC/arc.m
+++ b/clang/test/CodeGenObjC/arc.m
@@ -578,18 +578,18 @@ void test22(_Bool cond) {
// CHECK: define void @test22(
// CHECK: [[COND:%.*]] = alloca i8,
// CHECK-NEXT: [[X:%.*]] = alloca i8*,
- // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
// CHECK-NEXT: [[RELVAL:%.*]] = alloca i8*
- // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
+ // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
// CHECK-NEXT: zext
// CHECK-NEXT: store
// CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]]
// CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
+ // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
// CHECK-NEXT: br i1 [[T1]],
// CHECK: br label
// CHECK: [[CALL:%.*]] = call i8* @test22_helper()
- // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
// CHECK-NEXT: store i8* [[CALL]], i8** [[RELVAL]]
+ // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
// CHECK-NEXT: br label
// CHECK: [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ]
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind
@@ -1790,3 +1790,52 @@ void test61(void) {
// CHECK-NEXT: call void @objc_release(i8* [[T0]])
// CHECK-NEXT: ret void
}
+
+// rdar://problem/9891815
+void test62(void) {
+ // CHECK: define void @test62()
+ // CHECK: [[I:%.*]] = alloca i32, align 4
+ // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CLEANUP_REQUIRED:%.*]] = alloca i1
+ extern id test62_make(void);
+ extern void test62_body(void);
+
+ // CHECK-NEXT: store i32 0, i32* [[I]], align 4
+ // CHECK-NEXT: br label
+
+ // CHECK: [[T0:%.*]] = load i32* [[I]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 20
+ // CHECK-NEXT: br i1 [[T1]],
+
+ for (unsigned i = 0; i != 20; ++i) {
+ // CHECK: [[T0:%.*]] = load i32* [[I]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+ // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]]
+ // CHECK-NEXT: br i1 [[T1]],
+ // CHECK: [[T0:%.*]] = call i8* @test62_make()
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]]
+ // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]]
+ // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null
+ // CHECK-NEXT: br label
+ // CHECK: [[COND:%.*]] = phi i1 [ false, {{%.*}} ], [ [[T2]], {{%.*}} ]
+ // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_REQUIRED]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[CLEANUP_VALUE]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+ // CHECK-NEXT: br label
+ // CHECK: br i1 [[COND]]
+ // CHECK: call void @test62_body()
+ // CHECK-NEXT: br label
+ // CHECK: br label
+ if (i != 0 && test62_make() != 0)
+ test62_body();
+ }
+
+ // CHECK: [[T0:%.*]] = load i32* [[I]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], 1
+ // CHECK-NEXT: store i32 [[T1]], i32* [[I]]
+ // CHECK-NEXT: br label
+
+ // CHECK: ret void
+}
OpenPOWER on IntegriCloud