Skip to content

Commit 257132a

Browse files
author
Anastasia Stulova
committedSep 7, 2017
[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 llvm-svn: 312728
1 parent 20489ec commit 257132a

File tree

3 files changed

+24
-14
lines changed

3 files changed

+24
-14
lines changed
 

‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -7349,8 +7349,8 @@ def err_invalid_conversion_between_vector_and_integer : Error<
73497349
def err_opencl_function_pointer : Error<
73507350
"pointers to functions are not allowed">;
73517351

7352-
def err_opencl_taking_function_address : Error<
7353-
"taking address of function is not allowed">;
7352+
def err_opencl_taking_address_capture : Error<
7353+
"taking address of a capture is not allowed">;
73547354

73557355
def err_invalid_conversion_between_vector_and_scalar : Error<
73567356
"invalid conversion between vector type %0 and scalar type %1">;

‎clang/lib/Sema/SemaExpr.cpp

+11-12
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,6 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
425425
assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
426426

427427
if (Ty->isFunctionType()) {
428-
// If we are here, we are not calling a function but taking
429-
// its address (which is not allowed in OpenCL v1.0 s6.8.a.3).
430-
if (getLangOpts().OpenCL) {
431-
if (Diagnose)
432-
Diag(E->getExprLoc(), diag::err_opencl_taking_function_address);
433-
return ExprError();
434-
}
435-
436428
if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
437429
if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl()))
438430
if (!checkAddressOfFunctionIsAvailable(FD, Diagnose, E->getExprLoc()))
@@ -10869,10 +10861,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
1086910861
// Make sure to ignore parentheses in subsequent checks
1087010862
Expr *op = OrigOp.get()->IgnoreParens();
1087110863

10872-
// OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
10873-
if (LangOpts.OpenCL && op->getType()->isFunctionType()) {
10874-
Diag(op->getExprLoc(), diag::err_opencl_taking_function_address);
10875-
return QualType();
10864+
// In OpenCL captures for blocks called as lambda functions
10865+
// are located in the private address space. Blocks used in
10866+
// enqueue_kernel can be located in a different address space
10867+
// depending on a vendor implementation. Thus preventing
10868+
// taking an address of the capture to avoid invalid AS casts.
10869+
if (LangOpts.OpenCL) {
10870+
auto* VarRef = dyn_cast<DeclRefExpr>(op);
10871+
if (VarRef && VarRef->refersToEnclosingVariableOrCapture()) {
10872+
Diag(op->getExprLoc(), diag::err_opencl_taking_address_capture);
10873+
return QualType();
10874+
}
1087610875
}
1087710876

1087810877
if (getLangOpts().C99) {

‎clang/test/SemaOpenCL/invalid-block.cl

+11
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,14 @@ kernel void f7() {
8181
};
8282
return;
8383
}
84+
85+
// Taking address of a capture is not allowed
86+
int g;
87+
kernel void f8(int a1) {
88+
int a2;
89+
void (^bl)(void) = ^(void) {
90+
&g; //expected-warning{{expression result unused}}
91+
&a1; //expected-error{{taking address of a capture is not allowed}}
92+
&a2; //expected-error{{taking address of a capture is not allowed}}
93+
};
94+
}

0 commit comments

Comments
 (0)