Akira Hatanaka | 627586b | 2018-03-02 01:53:15 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -fno-escaping-block-tail-calls -emit-llvm -o - %s | FileCheck %s |
| 2 | |
| 3 | // CHECK-LABEL: define void @test( |
| 4 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE0:.*]] to i8*) |
| 5 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE1:.*]] to i8*) |
| 6 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE2:.*]] to i8*) |
| 7 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE3:.*]] to i8*) |
| 8 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE4:.*]] to i8*) |
| 9 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE5:.*]] to i8*) |
| 10 | // CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE6:.*]] to i8*) |
| 11 | |
| 12 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE0]]({{.*}}) #[[DISABLEATTR:.*]] { |
| 13 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE1]]({{.*}}) #[[ENABLEATTR:.*]] { |
| 14 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE2]]({{.*}}) #[[DISABLEATTR]] { |
| 15 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE3]]({{.*}}) #[[DISABLEATTR]] { |
| 16 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE4]]({{.*}}) #[[ENABLEATTR]] { |
| 17 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE5]]({{.*}}) #[[DISABLEATTR]] { |
| 18 | // CHECK: define internal void @[[TEST_BLOCK_INVOKE6]]({{.*}}) #[[ENABLEATTR]] { |
| 19 | |
| 20 | // CHECK: attributes #[[ENABLEATTR]] = {{{.*}}"disable-tail-calls"="false"{{.*}}} |
| 21 | // CHECK: attributes #[[DISABLEATTR]] = {{{.*}}"disable-tail-calls"="true"{{.*}}} |
| 22 | |
| 23 | typedef void (^BlockTy)(void); |
| 24 | typedef void (*NoEscapeFnTy)(__attribute__((noescape)) BlockTy); |
| 25 | |
| 26 | void callee0(__attribute__((noescape)) BlockTy); |
| 27 | void callee1(BlockTy); |
| 28 | |
| 29 | __attribute__((objc_root_class)) |
| 30 | @interface C0 |
| 31 | -(void)m0:(__attribute__((noescape)) BlockTy)p; |
| 32 | -(void)m1:(BlockTy)p; |
| 33 | @end |
| 34 | |
| 35 | @implementation C0 |
| 36 | -(void)m0:(__attribute__((noescape)) BlockTy)p {} |
| 37 | -(void)m1:(BlockTy)p {} |
| 38 | @end |
| 39 | |
| 40 | NoEscapeFnTy noescapefunc; |
| 41 | |
| 42 | void test(id a, C0 *c0) { |
| 43 | BlockTy b0 = ^{ (void)a; }; // disable tail-call optimization. |
| 44 | callee0(b0); |
| 45 | callee0(^{ (void)a; }); // enable tail-call optimization. |
| 46 | callee1(^{ (void)a; }); // disable tail-call optimization. |
| 47 | |
| 48 | BlockTy b1 = ^{ (void)a; }; // disable tail-call optimization. |
| 49 | [c0 m0:b1]; |
| 50 | [c0 m0:^{ (void)a; }]; // enable tail-call optimization. |
| 51 | [c0 m1:^{ (void)a; }]; // disable tail-call optimization. |
| 52 | |
| 53 | noescapefunc(^{ (void)a; }); // enable tail-call optimization. |
| 54 | } |