summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2016-10-28 12:59:39 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2016-10-28 12:59:39 +0000
commit7c3053336233772ff33d4f908fc954566a7e6422 (patch)
treecaf102e9ecac012b5720553784d677689d37f5d7
parentc3ccf5d77baa8cf4237e3eb68858eda97155e037 (diff)
downloadbcm5719-llvm-7c3053336233772ff33d4f908fc954566a7e6422.tar.gz
bcm5719-llvm-7c3053336233772ff33d4f908fc954566a7e6422.zip
[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. llvm-svn: 285395
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Headers/opencl-c.h2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp11
-rw-r--r--clang/lib/Sema/SemaType.cpp23
-rw-r--r--clang/test/SemaOpenCL/builtin.cl2
-rw-r--r--clang/test/SemaOpenCL/func.cl (renamed from clang/test/SemaOpenCL/func_ptr.cl)7
-rw-r--r--clang/test/SemaOpenCL/invalid-block.cl27
7 files changed, 47 insertions, 29 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a715731f239..9d375c7239d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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_function_parameter : Error <
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<
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index f8e132040d6..3eb6dc712f3 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -15459,9 +15459,11 @@ half16 __ovld __cnfn shuffle2(half8 x, half8 y, ushort16 mask);
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
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a94ed532944..f91e9dcdd6d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6888,17 +6888,6 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
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.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 2d612e5a0f9..4e6725eb626 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -4043,13 +4043,26 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
}
+ 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
diff --git a/clang/test/SemaOpenCL/builtin.cl b/clang/test/SemaOpenCL/builtin.cl
index d48a0c44959..c4d3a2399fe 100644
--- a/clang/test/SemaOpenCL/builtin.cl
+++ b/clang/test/SemaOpenCL/builtin.cl
@@ -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
diff --git a/clang/test/SemaOpenCL/func_ptr.cl b/clang/test/SemaOpenCL/func.cl
index abeab73a779..ea3bab6c514 100644
--- a/clang/test/SemaOpenCL/func_ptr.cl
+++ b/clang/test/SemaOpenCL/func.cl
@@ -1,5 +1,12 @@
// 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()
diff --git a/clang/test/SemaOpenCL/invalid-block.cl b/clang/test/SemaOpenCL/invalid-block.cl
index 6721d0ea234..a9eac1c2b58 100644
--- a/clang/test/SemaOpenCL/invalid-block.cl
+++ b/clang/test/SemaOpenCL/invalid-block.cl
@@ -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}}
}
OpenPOWER on IntegriCloud