Author: stulova Date: Fri Oct 28 07:59:39 2016 New Revision: 285395 URL: http://llvm.org/viewvc/llvm-project?rev=285395&view=rev Log: [OpenCL] Diagnose variadic arguments
OpenCL disallows using variadic arguments (s6.9.e and s6.12.5 OpenCL v2.0) apart from some exceptions: - printf - enqueue_kernel This change adds error diagnostic for variadic functions but accepts printf and any compiler internal function (which should cover __enqueue_kernel_XXX cases). It also unifies diagnostic with block prototype and adds missing uncaught cases for blocks. Added: cfe/trunk/test/SemaOpenCL/func.cl Removed: cfe/trunk/test/SemaOpenCL/func_ptr.cl Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Headers/opencl-c.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/SemaOpenCL/builtin.cl 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=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 28 07:59:39 2016 @@ -8080,8 +8080,6 @@ def err_atomic_init_constant : Error< " in the declaration statement in the program scope">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; -def err_opencl_block_proto_variadic : Error< - "invalid block prototype, variadic arguments are not allowed in OpenCL">; def err_opencl_invalid_type_array : Error< "array of %0 type is invalid in OpenCL">; def err_opencl_ternary_with_block : Error< @@ -8093,6 +8091,8 @@ def err_opencl_type_can_only_be_used_as_ def warn_opencl_attr_deprecated_ignored : Warning < "%0 attribute is deprecated and ignored in OpenCL version %1">, InGroup<IgnoredAttributes>; +def err_opencl_variadic_function : Error< + "invalid prototype, variadic arguments are not allowed in OpenCL">; // OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions def err_opencl_builtin_pipe_first_arg : Error< Modified: cfe/trunk/lib/Headers/opencl-c.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/opencl-c.h?rev=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/lib/Headers/opencl-c.h (original) +++ cfe/trunk/lib/Headers/opencl-c.h Fri Oct 28 07:59:39 2016 @@ -15459,9 +15459,11 @@ half16 __ovld __cnfn shuffle2(half8 x, h half16 __ovld __cnfn shuffle2(half16 x, half16 y, ushort16 mask); #endif //cl_khr_fp16 +#if __OPENCL_C_VERSION__ >= CL_VERSION_1_2 // OpenCL v1.2 s6.12.13, v2.0 s6.13.13 - printf int printf(__constant const char* st, ...); +#endif // OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14 - Image Read and Write Functions Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 28 07:59:39 2016 @@ -6888,17 +6888,6 @@ void Sema::CheckVariableDeclarationType( NewVD->setInvalidDecl(); return; } - // OpenCL v2.0 s6.12.5 - Blocks with variadic arguments are not supported. - // TODO: this check is not enough as it doesn't diagnose the typedef - const BlockPointerType *BlkTy = T->getAs<BlockPointerType>(); - const FunctionProtoType *FTy = - BlkTy->getPointeeType()->getAs<FunctionProtoType>(); - if (FTy && FTy->isVariadic()) { - Diag(NewVD->getLocation(), diag::err_opencl_block_proto_variadic) - << T << NewVD->getSourceRange(); - NewVD->setInvalidDecl(); - return; - } } // OpenCL v1.2 s6.5 - All program scope variables must be declared in the // __constant address space. Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Fri Oct 28 07:59:39 2016 @@ -4043,13 +4043,26 @@ static TypeSourceInfo *GetFullTypeForDec } } + if (LangOpts.OpenCL) { // OpenCL v2.0 s6.12.5 - A block cannot be the return value of a // function. - if (LangOpts.OpenCL && (T->isBlockPointerType() || T->isImageType() || - T->isSamplerT() || T->isPipeType())) { - S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return) - << T << 1 /*hint off*/; - D.setInvalidType(true); + if (T->isBlockPointerType() || T->isImageType() || T->isSamplerT() || + T->isPipeType()) { + S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return) + << T << 1 /*hint off*/; + D.setInvalidType(true); + } + // OpenCL doesn't support variadic functions and blocks + // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. + // We also allow here any toolchain reserved identifiers. + if (FTI.isVariadic && + !(D.getIdentifier() && + ((D.getIdentifier()->getName() == "printf" && + LangOpts.OpenCLVersion >= 120) || + D.getIdentifier()->getName().startswith("__")))) { + S.Diag(D.getIdentifierLoc(), diag::err_opencl_variadic_function); + D.setInvalidType(true); + } } // Methods cannot return interface types. All ObjC objects are Modified: cfe/trunk/test/SemaOpenCL/builtin.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/builtin.cl?rev=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/test/SemaOpenCL/builtin.cl (original) +++ cfe/trunk/test/SemaOpenCL/builtin.cl Fri Oct 28 07:59:39 2016 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 // expected-no-diagnostics Added: cfe/trunk/test/SemaOpenCL/func.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/func.cl?rev=285395&view=auto ============================================================================== --- cfe/trunk/test/SemaOpenCL/func.cl (added) +++ cfe/trunk/test/SemaOpenCL/func.cl Fri Oct 28 07:59:39 2016 @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +// Variadic functions +void vararg_f(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} +void __vararg_f(int, ...); +typedef void (*vararg_fptr_t)(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} +int printf(__constant const char *st, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} + +//Function pointer +void foo(void*); + +void bar() +{ + // declaring a function pointer is an error + void (*fptr)(int); // expected-error{{pointers to functions are not allowed}} + + // taking the address of a function is an error + foo((void*)foo); // expected-error{{taking address of function is not allowed}} + foo(&foo); // expected-error{{taking address of function is not allowed}} + + // initializing an array with the address of functions is an error + void* vptrarr[2] = {foo, &foo}; // expected-error{{taking address of function is not allowed}} expected-error{{taking address of function is not allowed}} + + // just calling a function is correct + foo(0); +} Removed: cfe/trunk/test/SemaOpenCL/func_ptr.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/func_ptr.cl?rev=285394&view=auto ============================================================================== --- cfe/trunk/test/SemaOpenCL/func_ptr.cl (original) +++ cfe/trunk/test/SemaOpenCL/func_ptr.cl (removed) @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only - -void foo(void*); - -void bar() -{ - // declaring a function pointer is an error - void (*fptr)(int); // expected-error{{pointers to functions are not allowed}} - - // taking the address of a function is an error - foo((void*)foo); // expected-error{{taking address of function is not allowed}} - foo(&foo); // expected-error{{taking address of function is not allowed}} - - // initializing an array with the address of functions is an error - void* vptrarr[2] = {foo, &foo}; // expected-error{{taking address of function is not allowed}} expected-error{{taking address of function is not allowed}} - - // just calling a function is correct - foo(0); -} Modified: cfe/trunk/test/SemaOpenCL/invalid-block.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/invalid-block.cl?rev=285395&r1=285394&r2=285395&view=diff ============================================================================== --- cfe/trunk/test/SemaOpenCL/invalid-block.cl (original) +++ cfe/trunk/test/SemaOpenCL/invalid-block.cl Fri Oct 28 07:59:39 2016 @@ -31,23 +31,30 @@ void f4() { } // A block with variadic argument is not allowed. -int (^bl)(int, ...) = ^int(int I, ...) { // expected-error {{invalid block prototype, variadic arguments are not allowed in OpenCL}} +int (^bl)(int, ...) = ^int(int I, ...) { // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} return 0; }; +typedef int (^bl1_t)(int, ...); // expected-error {{invalid prototype, variadic arguments are not allowed in OpenCL}} // A block can't be used to declare an array -typedef int (^bl1_t)(int); +typedef int (^bl2_t)(int); void f5(int i) { - bl1_t bl1 = ^(int i) {return 1;}; - bl1_t bl2 = ^(int i) {return 2;}; - bl1_t arr[] = {bl1, bl2}; // expected-error {{array of 'bl1_t' (aka 'int (^const)(int)') type is invalid in OpenCL}} + bl2_t bl1 = ^(int i) { + return 1; + }; + bl2_t bl2 = ^(int i) { + return 2; + }; + bl2_t arr[] = {bl1, bl2}; // expected-error {{array of 'bl2_t' (aka 'int (^const)(int)') type is invalid in OpenCL}} int tmp = i ? bl1(i) // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}} : bl2(i); // expected-error {{block type cannot be used as expression in ternary expression in OpenCL}} } // A block pointer type and all pointer operations are disallowed -void f6(bl1_t * bl_ptr) { // expected-error{{pointer to type '__generic bl1_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} - bl1_t bl = ^(int i) {return 1;}; - bl1_t *p; // expected-error {{pointer to type '__generic bl1_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} - *bl; // expected-error {{invalid argument type 'bl1_t' (aka 'int (^const)(int)') to unary expression}} - &bl; // expected-error {{invalid argument type 'bl1_t' (aka 'int (^const)(int)') to unary expression}} +void f6(bl2_t *bl_ptr) { // expected-error{{pointer to type '__generic bl2_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} + bl2_t bl = ^(int i) { + return 1; + }; + bl2_t *p; // expected-error {{pointer to type '__generic bl2_t' (aka 'int (^const __generic)(int)') is invalid in OpenCL}} + *bl; // expected-error {{invalid argument type 'bl2_t' (aka 'int (^const)(int)') to unary expression}} + &bl; // expected-error {{invalid argument type 'bl2_t' (aka 'int (^const)(int)') to unary expression}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits