teak-llvm/clang/test/CodeGenObjC/blocks-1.m
Akira Hatanaka 8e57b07f66 Distinguish __block variables that are captured by escaping blocks
from those that aren't.

This patch changes the way __block variables that aren't captured by
escaping blocks are handled:

- Since non-escaping blocks on the stack never get copied to the heap
  (see https://reviews.llvm.org/D49303), Sema shouldn't error out when
  the type of a non-escaping __block variable doesn't have an accessible
  copy constructor.

- IRGen doesn't have to use the specialized byref structure (see
  https://clang.llvm.org/docs/Block-ABI-Apple.html#id8) for a
  non-escaping __block variable anymore. Instead IRGen can emit the
  variable as a normal variable and copy the reference to the block
  literal. Byref copy/dispose helpers aren't needed either.

This reapplies r343518 after fixing a use-after-free bug in function
Sema::ActOnBlockStmtExpr where the BlockScopeInfo was dereferenced after
it was popped and deleted.

rdar://problem/39352313

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

llvm-svn: 343542
2018-10-01 21:51:28 +00:00

53 lines
1.5 KiB
Objective-C

// RUN: %clang_cc1 %s -emit-llvm -o - -fobjc-gc -fblocks -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 | FileCheck %s --check-prefix=CHECK --check-prefix=OBJC
// RUN: %clang_cc1 -x objective-c++ %s -emit-llvm -o - -fobjc-gc -fblocks -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 | FileCheck %s --check-prefix=CHECK --check-prefix=OBJCXX
// OBJC-LABEL: define void @test1(
// OBJCXX-LABEL: define void @_Z5test1P12NSDictionary(
// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_
// CHECK: call void @_Block_object_assign(
// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_
// CHECK: call void @_Block_object_dispose(
// OBJC-LABEL: define void @foo(
// OBJCXX-LABEL: define void @_Z3foov(
// CHECK: call i8* @objc_read_weak(
// CHECK: call i8* @objc_assign_weak(
// CHECK: call void @_Block_object_dispose(
// OBJC-LABEL: define void @test2(
// OBJCXX-LABEL: define void @_Z5test2v(
// CHECK: call i8* @objc_assign_weak(
// CHECK: call void @_Block_object_dispose(
// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_
// CHECK: call void @_Block_object_assign(
// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_
// CHECK: call void @_Block_object_dispose(
@interface NSDictionary @end
void test1(NSDictionary * dict) {
^{ (void)dict; }();
}
@interface D
@end
void foo() {
__block __weak D *weakSelf;
^{ (void)weakSelf; };
D *l;
l = weakSelf;
weakSelf = l;
}
void (^__weak b)(void);
void test2() {
__block int i = 0;
b = ^ { ++i; };
}