r285395 - [OpenCL] Diagnose variadic arguments

Anastasia Stulova via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 28 05:59:39 PDT 2016


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}}
 }




More information about the cfe-commits mailing list