diff options
author | John McCall <rjmccall@apple.com> | 2011-08-03 22:24:24 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-03 22:24:24 +0000 |
commit | 9c8e1c9401fac74a10ccfcfe174214be91dbb772 (patch) | |
tree | ac9e6894a920af3c612be98c5640783b627b1b81 /clang/test/CodeGenObjC/arc.m | |
parent | 2d3138c112cf2f15ab1c131f5f0af0a1cbe76391 (diff) | |
download | bcm5719-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.m | 55 |
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 +} |