teak-llvm/clang/test/CodeGenObjC/disable-tail-call-escaping-block.m
Akira Hatanaka 627586b850 Add an option to disable tail-call optimization for escaping blocks.
This makes it easier to debug crashes and hangs in block functions since
users can easily find out where the block is called from. The option
doesn't disable tail-calls from non-escaping blocks since non-escaping
blocks are not as hard to debug as escaping blocks.

rdar://problem/35758207

Differential Revision: https://reviews.llvm.org/D43841

llvm-svn: 326530
2018-03-02 01:53:15 +00:00

55 lines
2.3 KiB
Objective-C

// 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.
}