diff options
Diffstat (limited to 'clang/test/CodeGenObjC/disable-tail-call-escaping-block.m')
-rw-r--r-- | clang/test/CodeGenObjC/disable-tail-call-escaping-block.m | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m b/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m new file mode 100644 index 00000000000..48b0eda5a56 --- /dev/null +++ b/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -fno-escaping-block-tail-calls -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: define void @test( +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE0:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE1:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE2:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE3:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE4:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE5:.*]] to i8*) +// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE6:.*]] to i8*) + +// CHECK: define internal void @[[TEST_BLOCK_INVOKE0]]({{.*}}) #[[DISABLEATTR:.*]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE1]]({{.*}}) #[[ENABLEATTR:.*]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE2]]({{.*}}) #[[DISABLEATTR]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE3]]({{.*}}) #[[DISABLEATTR]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE4]]({{.*}}) #[[ENABLEATTR]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE5]]({{.*}}) #[[DISABLEATTR]] { +// CHECK: define internal void @[[TEST_BLOCK_INVOKE6]]({{.*}}) #[[ENABLEATTR]] { + +// CHECK: attributes #[[ENABLEATTR]] = {{{.*}}"disable-tail-calls"="false"{{.*}}} +// CHECK: attributes #[[DISABLEATTR]] = {{{.*}}"disable-tail-calls"="true"{{.*}}} + +typedef void (^BlockTy)(void); +typedef void (*NoEscapeFnTy)(__attribute__((noescape)) BlockTy); + +void callee0(__attribute__((noescape)) BlockTy); +void callee1(BlockTy); + +__attribute__((objc_root_class)) +@interface C0 +-(void)m0:(__attribute__((noescape)) BlockTy)p; +-(void)m1:(BlockTy)p; +@end + +@implementation C0 +-(void)m0:(__attribute__((noescape)) BlockTy)p {} +-(void)m1:(BlockTy)p {} +@end + +NoEscapeFnTy noescapefunc; + +void test(id a, C0 *c0) { + BlockTy b0 = ^{ (void)a; }; // disable tail-call optimization. + callee0(b0); + callee0(^{ (void)a; }); // enable tail-call optimization. + callee1(^{ (void)a; }); // disable tail-call optimization. + + BlockTy b1 = ^{ (void)a; }; // disable tail-call optimization. + [c0 m0:b1]; + [c0 m0:^{ (void)a; }]; // enable tail-call optimization. + [c0 m1:^{ (void)a; }]; // disable tail-call optimization. + + noescapefunc(^{ (void)a; }); // enable tail-call optimization. +} |