]> granicus.if.org Git - clang/commitdiff
[OpenCL] Allow blocks to capture arrays in OpenCL
authorAndrew Savonichev <andrew.savonichev@intel.com>
Mon, 17 Sep 2018 11:19:42 +0000 (11:19 +0000)
committerAndrew Savonichev <andrew.savonichev@intel.com>
Mon, 17 Sep 2018 11:19:42 +0000 (11:19 +0000)
Summary: Patch by Egor Churaev

Reviewers: Anastasia, yaxunl

Reviewed By: Anastasia

Subscribers: asavonic, bader, cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@342370 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaOpenCL/block-array-capturing.cl [new file with mode: 0644]

index 45510da0b1a7ed97ab1cc1ee4e4b473dca26cff6..5bf7098dfa24e2a93b3301e90ede6635ab030533 100644 (file)
@@ -14627,8 +14627,10 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var,
   Expr *CopyExpr = nullptr;
   bool ByRef = false;
 
-  // Blocks are not allowed to capture arrays.
-  if (CaptureType->isArrayType()) {
+  // Blocks are not allowed to capture arrays, excepting OpenCL.
+  // OpenCL v2.0 s1.12.5 (revision 40): arrays are captured by reference
+  // (decayed to pointers).
+  if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) {
     if (BuildAndDiagnose) {
       S.Diag(Loc, diag::err_ref_array_type);
       S.Diag(Var->getLocation(), diag::note_previous_decl)
diff --git a/test/SemaOpenCL/block-array-capturing.cl b/test/SemaOpenCL/block-array-capturing.cl
new file mode 100644 (file)
index 0000000..2e922ad
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s
+// expected-no-diagnostics
+
+typedef int (^block_t)();
+
+int block_typedef_kernel(global int* res) {
+  // CHECK: %{{.*}} = alloca <{ i32, i32, [3 x i32] }>
+  int a[3] = {1, 2, 3};
+  // CHECK: call void @llvm.memcpy{{.*}}
+  block_t b = ^() { return a[0]; };
+  return b();
+}
+
+// CHECK: define {{.*}} @__block_typedef_kernel_block_invoke
+// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* %{{.*}}, i64 0, i64 0
+// CHECK-NOT: call void @llvm.memcpy{{.*}}