Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -13643,7 +13643,7 @@ bool ByRef = false; // Blocks are not allowed to capture arrays. - if (CaptureType->isArrayType()) { + if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) { if (BuildAndDiagnose) { S.Diag(Loc, diag::err_ref_array_type); S.Diag(Var->getLocation(), diag::note_previous_decl) Index: test/SemaOpenCL/blocks_with_array.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/blocks_with_array.cl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -O0 -fblocks -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s + +typedef int (^block_t)(); + +int block_typedef_kernel(global int* res) { + int a[3] = {1, 2, 3}; + block_t b = ^() { +// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* %{{.*}}, i64 0, i64 0 + return a[0]; + }; + return b(); +} + +// CHECK: define spir_func void @foo() +void foo() { + struct v { + int arr[2]; + } s = {0, 1}; + block_t bl1 = ^(){return s.arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds %struct.v, %struct.v addrspace(4)* %{{.*}}, i32 0, i32 0 +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array content copied into captured struct location + int arr[2] = {0, 1}; + block_t bl2 = ^(){return arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke_2(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array decayed to pointer while captured + s.arr[1] = arr[1] = 877; +}