This revision was automatically updated to reflect the committed changes. Closed by commit rL312728: [OpenCL] Handle taking an address of block captures. (authored by stulova).
Changed prior to commit: https://reviews.llvm.org/D36410?vs=110015&id=114197#toc Repository: rL LLVM https://reviews.llvm.org/D36410 Files: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/SemaOpenCL/invalid-block.cl Index: cfe/trunk/test/SemaOpenCL/invalid-block.cl =================================================================== --- cfe/trunk/test/SemaOpenCL/invalid-block.cl +++ cfe/trunk/test/SemaOpenCL/invalid-block.cl @@ -81,3 +81,14 @@ }; 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}} + }; +} Index: cfe/trunk/lib/Sema/SemaExpr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp +++ cfe/trunk/lib/Sema/SemaExpr.cpp @@ -425,14 +425,6 @@ 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 @@ // 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) { Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -7349,8 +7349,8 @@ 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">;
Index: cfe/trunk/test/SemaOpenCL/invalid-block.cl =================================================================== --- cfe/trunk/test/SemaOpenCL/invalid-block.cl +++ cfe/trunk/test/SemaOpenCL/invalid-block.cl @@ -81,3 +81,14 @@ }; 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}} + }; +} Index: cfe/trunk/lib/Sema/SemaExpr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp +++ cfe/trunk/lib/Sema/SemaExpr.cpp @@ -425,14 +425,6 @@ 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 @@ // 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) { Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -7349,8 +7349,8 @@ 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">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits