[OpenCL] Disallow blocks capture other blocks (v2.0, s6.12.5)

llvm-svn: 295307
This commit is contained in:
Anastasia Stulova 2017-02-16 11:13:30 +00:00
parent a93803b9fe
commit 9d98a316c5
3 changed files with 24 additions and 0 deletions

View File

@ -8299,6 +8299,8 @@ def err_opencl_invalid_block_declaration : Error<
"invalid block variable declaration - must be %select{const qualified|initialized}0">;
def err_opencl_extern_block_declaration : Error<
"invalid block variable declaration - using 'extern' storage class is disallowed">;
def err_opencl_block_ref_block : Error<
"cannot refer to a block inside block">;
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
def err_opencl_builtin_to_addr_arg_num : Error<

View File

@ -13565,6 +13565,13 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var,
}
return false;
}
// OpenCL v2.0 s6.12.5: Blocks cannot reference/capture other blocks
if (S.getLangOpts().OpenCL && IsBlock &&
Var->getType()->isBlockPointerType()) {
if (Diagnose)
S.Diag(Loc, diag::err_opencl_block_ref_block);
return false;
}
return true;
}

View File

@ -66,3 +66,18 @@ void f6(bl2_t *bl_ptr) { // expected-error{{pointer to type '__generic bl2_t' (a
*bl; // expected-error {{invalid argument type 'bl2_t' (aka 'int (__generic ^const)(int)') to unary expression}}
&bl; // expected-error {{invalid argument type 'bl2_t' (aka 'int (__generic ^const)(int)') to unary expression}}
}
// A block can't reference another block
kernel void f7() {
bl2_t bl1 = ^(int i) {
return 1;
};
void (^bl2)(void) = ^{
int i = bl1(1); // expected-error {{cannot refer to a block inside block}}
};
void (^bl3)(void) = ^{
};
void (^bl4)(void) = ^{
bl3(); // expected-error {{cannot refer to a block inside block}}
};
return;
}