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 | } |
55 | |