olestrohm updated this revision to Diff 339197.
olestrohm added a comment.
Ran git-clang-format.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100860/new/
https://reviews.llvm.org/D100860
Files:
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaOpenCL/clk_event_t.cl
clang/test/SemaOpenCL/event_t.cl
clang/test/SemaOpenCL/sampler_t.cl
clang/test/SemaOpenCLCXX/template-diagnostics.clcpp
Index: clang/test/SemaOpenCLCXX/template-diagnostics.clcpp
===================================================================
--- /dev/null
+++ clang/test/SemaOpenCLCXX/template-diagnostics.clcpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only
+
+template<typename T>
+T global_variable; //expected-error{{the '__global clk_event_t' type cannot be used to declare a program scope variable}}
+
+clk_event_t global_event; //expected-error{{the '__global clk_event_t' type cannot be used to declare a program scope variable}}
+
+template<typename T>
+void templ() {
+ T loc;
+ //expected-error@-1{{type '__private __read_only image1d_t' can only be used as a function parameter in OpenCL}}
+ //expected-error@-2{{declaring variable of type '__private half' is not allowed}}
+ //expected-error@-3{{non-kernel function variable cannot be declared in local address space}}
+}
+
+void foo() {
+ templ<image1d_t>(); //expected-note{{in instantiation of function template specialization 'templ<__read_only image1d_t>' requested here}}
+ templ<half>(); //expected-note{{in instantiation of function template specialization 'templ<half>' requested here}}
+ templ<__local event_t>(); //expected-note{{in instantiation of function template specialization 'templ<__local event_t>' requested here}}
+
+ image1d_t img; //expected-error{{type '__private __read_only image1d_t' can only be used as a function parameter in OpenCL}}
+ half h; //expected-error{{declaring variable of type '__private half' is not allowed}}
+ __local event_t e; //expected-error{{the event_t type can only be used with __private address space qualifier}}
+
+ (void) global_variable<clk_event_t>; // expected-note{{in instantiation of variable template specialization 'global_variable' requested here}}
+}
Index: clang/test/SemaOpenCL/sampler_t.cl
===================================================================
--- clang/test/SemaOpenCL/sampler_t.cl
+++ clang/test/SemaOpenCL/sampler_t.cl
@@ -48,9 +48,6 @@
sampler_t bad(void); //expected-error{{declaring function return value of type 'sampler_t' is not allowed}}
sampler_t global_nonconst_smp = 0; // expected-error {{global sampler requires a const or constant address space qualifier}}
-#ifdef CHECK_SAMPLER_VALUE
-// expected-warning@-2{{sampler initializer has invalid Filter Mode bits}}
-#endif
const sampler_t glb_smp10 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
const constant sampler_t glb_smp11 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
Index: clang/test/SemaOpenCL/event_t.cl
===================================================================
--- clang/test/SemaOpenCL/event_t.cl
+++ clang/test/SemaOpenCL/event_t.cl
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
-event_t glb_evt; // expected-error {{the '__private event_t' type cannot be used to declare a program scope variable}} expected-error{{program scope variable must reside in constant address space}}
+event_t glb_evt; // expected-error {{the '__private event_t' type cannot be used to declare a program scope variable}}
constant struct evt_s {
event_t evt; // expected-error {{the 'event_t' type cannot be used to declare a structure or union field}}
@@ -10,7 +10,7 @@
void kernel ker(event_t argevt) { // expected-error {{'__private event_t' cannot be used as the type of a kernel parameter}}
event_t e;
- constant event_t const_evt; // expected-error {{the event_t type can only be used with __private address space qualifier}} expected-error{{variable in constant address space must be initialized}}
+ constant event_t const_evt; // expected-error{{the '__constant event_t' type cannot be used to declare a program scope variable}}
foo(e);
foo(0);
foo(5); // expected-error {{passing 'int' to parameter of incompatible type 'event_t'}}
Index: clang/test/SemaOpenCL/clk_event_t.cl
===================================================================
--- clang/test/SemaOpenCL/clk_event_t.cl
+++ clang/test/SemaOpenCL/clk_event_t.cl
@@ -12,6 +12,9 @@
clk_event_t ce2;
clk_event_t ce3 = CLK_NULL_EVENT;
+ // FIXME: Not obvious if this should give an error as if it was in program scope.
+ static clk_event_t ce4;
+
if (e == ce1) { // expected-error {{invalid operands to binary expression ('__private event_t' and '__private clk_event_t')}}
return 9;
}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6724,17 +6724,20 @@
llvm_unreachable("Unknown type of decl!");
}
+
/// Returns true if there hasn't been any invalid type diagnosed.
-static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D,
- DeclContext *DC, QualType R) {
+static bool diagnoseOpenCLTypes(Sema &Se, VarDecl *NewVD) {
+ DeclContext *DC = NewVD->getDeclContext();
+ QualType R = NewVD->getType();
+
// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument.
// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function
// argument.
if (R->isImageType() || R->isPipeType()) {
- Se.Diag(D.getIdentifierLoc(),
+ Se.Diag(NewVD->getLocation(),
diag::err_opencl_type_can_only_be_used_as_function_parameter)
<< R;
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
@@ -6743,12 +6746,12 @@
// OpenCL v2.0 s6.9.q:
// The clk_event_t and reserve_id_t types cannot be declared in program
// scope.
- if (NULL == S->getParent()) {
+ if (NewVD->hasGlobalStorage() && !NewVD->isStaticLocal()) {
if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) {
- Se.Diag(D.getIdentifierLoc(),
+ Se.Diag(NewVD->getLocation(),
diag::err_invalid_type_for_program_scope_var)
<< R;
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
}
@@ -6761,9 +6764,9 @@
NR->isReferenceType()) {
if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType() ||
NR->isFunctionReferenceType()) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer)
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_function_pointer)
<< NR->isReferenceType();
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
NR = NR->getPointeeType();
@@ -6775,8 +6778,8 @@
// OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
// half array type (unless the cl_khr_fp16 extension is enabled).
if (Se.Context.getBaseElementType(R)->isHalfType()) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_half_declaration) << R;
+ NewVD->setInvalidDecl();
return false;
}
}
@@ -6786,34 +6789,20 @@
// address space qualifiers.
if (R->isEventT()) {
if (R.getAddressSpace() != LangAS::opencl_private) {
- Se.Diag(D.getBeginLoc(), diag::err_event_t_addr_space_qual);
- D.setInvalidType();
+ Se.Diag(NewVD->getBeginLoc(), diag::err_event_t_addr_space_qual);
+ NewVD->setInvalidDecl();
return false;
}
}
- // C++ for OpenCL does not allow the thread_local storage qualifier.
- // OpenCL C does not support thread_local either, and
- // also reject all other thread storage class specifiers.
- DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
- if (TSC != TSCS_unspecified) {
- bool IsCXX = Se.getLangOpts().OpenCLCPlusPlus;
- Se.Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
- diag::err_opencl_unknown_type_specifier)
- << IsCXX << Se.getLangOpts().getOpenCLVersionTuple().getAsString()
- << DeclSpec::getSpecifierName(TSC) << 1;
- D.setInvalidType();
- return false;
- }
-
if (R->isSamplerT()) {
// OpenCL v1.2 s6.9.b p4:
// The sampler type cannot be used with the __local and __global address
// space qualifiers.
if (R.getAddressSpace() == LangAS::opencl_local ||
R.getAddressSpace() == LangAS::opencl_global) {
- Se.Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_wrong_sampler_addressspace);
+ NewVD->setInvalidDecl();
}
// OpenCL v1.2 s6.12.14.1:
@@ -6822,12 +6811,13 @@
if (DC->isTranslationUnit() &&
!(R.getAddressSpace() == LangAS::opencl_constant ||
R.isConstQualified())) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_nonconst_global_sampler);
+ NewVD->setInvalidDecl();
}
- if (D.isInvalidType())
+ if (NewVD->isInvalidDecl())
return false;
}
+
return true;
}
@@ -7254,10 +7244,19 @@
}
if (getLangOpts().OpenCL) {
-
deduceOpenCLAddressSpace(NewVD);
- diagnoseOpenCLTypes(S, *this, D, DC, NewVD->getType());
+ diagnoseOpenCLTypes(*this, NewVD);
+
+ DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
+ if (TSC != TSCS_unspecified) {
+ bool IsCXX = getLangOpts().OpenCLCPlusPlus;
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_opencl_unknown_type_specifier)
+ << IsCXX << getLangOpts().getOpenCLVersionTuple().getAsString()
+ << DeclSpec::getSpecifierName(TSC) << 1;
+ NewVD->setInvalidDecl();
+ }
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
@@ -7942,6 +7941,7 @@
return;
}
}
+
// OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
// __constant address space.
// OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static
@@ -8013,6 +8013,9 @@
return;
}
}
+
+ if (!diagnoseOpenCLTypes(*this, NewVD))
+ return;
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits