r312728 - [OpenCL] Handle taking an address of block captures.

Anastasia Stulova via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 7 10:00:33 PDT 2017


Author: stulova
Date: Thu Sep  7 10:00:33 2017
New Revision: 312728

URL: http://llvm.org/viewvc/llvm-project?rev=312728&view=rev
Log:
[OpenCL] Handle taking an address of block captures.

Block captures can have different physical locations
in memory segments depending on the use case (as a function
call or as a kernel enqueue) and in different vendor
implementations.

Therefore it's unclear how to add address space to capture
addresses uniformly. Currently it has been decided to disallow
taking addresses of captured variables until further
clarifications in the spec.

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


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaOpenCL/invalid-block.cl

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=312728&r1=312727&r2=312728&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep  7 10:00:33 2017
@@ -7349,8 +7349,8 @@ def err_invalid_conversion_between_vecto
 def err_opencl_function_pointer : Error<
   "pointers to functions are not allowed">;
 
-def err_opencl_taking_function_address : Error<
-  "taking address of function is not allowed">;
+def err_opencl_taking_address_capture : Error<
+  "taking address of a capture is not allowed">;
 
 def err_invalid_conversion_between_vector_and_scalar : Error<
   "invalid conversion between vector type %0 and scalar type %1">;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=312728&r1=312727&r2=312728&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep  7 10:00:33 2017
@@ -425,14 +425,6 @@ ExprResult Sema::DefaultFunctionArrayCon
   assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
 
   if (Ty->isFunctionType()) {
-    // If we are here, we are not calling a function but taking
-    // its address (which is not allowed in OpenCL v1.0 s6.8.a.3).
-    if (getLangOpts().OpenCL) {
-      if (Diagnose)
-        Diag(E->getExprLoc(), diag::err_opencl_taking_function_address);
-      return ExprError();
-    }
-
     if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
       if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl()))
         if (!checkAddressOfFunctionIsAvailable(FD, Diagnose, E->getExprLoc()))
@@ -10869,10 +10861,17 @@ QualType Sema::CheckAddressOfOperand(Exp
   // Make sure to ignore parentheses in subsequent checks
   Expr *op = OrigOp.get()->IgnoreParens();
 
-  // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
-  if (LangOpts.OpenCL && op->getType()->isFunctionType()) {
-    Diag(op->getExprLoc(), diag::err_opencl_taking_function_address);
-    return QualType();
+  // In OpenCL captures for blocks called as lambda functions
+  // are located in the private address space. Blocks used in
+  // enqueue_kernel can be located in a different address space
+  // depending on a vendor implementation. Thus preventing
+  // taking an address of the capture to avoid invalid AS casts.
+  if (LangOpts.OpenCL) {
+    auto* VarRef = dyn_cast<DeclRefExpr>(op);
+    if (VarRef && VarRef->refersToEnclosingVariableOrCapture()) {
+      Diag(op->getExprLoc(), diag::err_opencl_taking_address_capture);
+      return QualType();
+    }
   }
 
   if (getLangOpts().C99) {

Modified: cfe/trunk/test/SemaOpenCL/invalid-block.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-block.cl?rev=312728&r1=312727&r2=312728&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/invalid-block.cl (original)
+++ cfe/trunk/test/SemaOpenCL/invalid-block.cl Thu Sep  7 10:00:33 2017
@@ -81,3 +81,14 @@ kernel void f7() {
   };
   return;
 }
+
+// Taking address of a capture is not allowed
+int g;
+kernel void f8(int a1) {
+  int a2;
+  void (^bl)(void) = ^(void) {
+    &g; //expected-warning{{expression result unused}}
+    &a1; //expected-error{{taking address of a capture is not allowed}}
+    &a2; //expected-error{{taking address of a capture is not allowed}}
+  };
+}




More information about the cfe-commits mailing list