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 23typedef void (^BlockTy)(void); 24typedef void (*NoEscapeFnTy)(__attribute__((noescape)) BlockTy); 25 26void callee0(__attribute__((noescape)) BlockTy); 27void 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 40NoEscapeFnTy noescapefunc; 41 42void 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