Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8073,8 +8073,6 @@ "within field of type %0 declared here">; def note_illegal_field_declared_here : Note< "field of illegal %select{type|pointer type}0 %1 declared here">; -def err_event_t_global_var : Error< - "the event_t type cannot be used to declare a program scope variable">; def err_opencl_type_struct_or_union_field : Error< "the %0 type cannot be used to declare a structure or union field">; def err_event_t_addr_space_qual : Error< @@ -8587,6 +8585,8 @@ def note_related_result_type_explicit : Note< "%select{overridden|current}0 method is explicitly declared 'instancetype'" "%select{| and is expected to return an instance of its class type}0">; +def err_invalid_type_for_program_scope_var : Error< + "the %0 type cannot be used to declare a program scope variable">; } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5909,32 +5909,30 @@ return nullptr; } - // 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 (getLangOpts().OpenCL && (R->isImageType() || R->isPipeType())) { - Diag(D.getIdentifierLoc(), - diag::err_opencl_type_can_only_be_used_as_function_parameter) - << R; - D.setInvalidType(); - return nullptr; - } - - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); - StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); - - // dllimport globals without explicit storage class are treated as extern. We - // have to change the storage class this early to get the right DeclContext. - if (SC == SC_None && !DC->isRecord() && - hasParsedAttr(S, D, AttributeList::AT_DLLImport) && - !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) - SC = SC_Extern; + if (getLangOpts().OpenCL) { + // 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()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << R; + D.setInvalidType(); + return nullptr; + } - DeclContext *OriginalDC = DC; - bool IsLocalExternDecl = SC == SC_Extern && - adjustContextForLocalExternDecl(DC); + // OpenCL 1.2 spec, p6.9 r: + // The event type cannot be used to declare a program scope variable. + // 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 (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) { + Diag(D.getIdentifierLoc(), + diag::err_invalid_type_for_program_scope_var) << R; + D.setInvalidType(); + return nullptr; + } + } - if (getLangOpts().OpenCL) { // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. QualType NR = R; while (NR->isPointerType()) { @@ -5954,8 +5952,40 @@ D.setInvalidType(); } } + + // OpenCL v1.2 s6.9.b p4: + // The sampler type cannot be used with the __local and __global address + // space qualifiers. + if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_local || + R.getAddressSpace() == LangAS::opencl_global)) { + Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); + } + + // OpenCL 1.2 spec, p6.9 r: + // The event type cannot be used with the __local, __constant and __global + // address space qualifiers. + if (R->isEventT()) { + if (R.getAddressSpace()) { + Diag(D.getLocStart(), diag::err_event_t_addr_space_qual); + D.setInvalidType(); + } + } } + DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); + StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); + + // dllimport globals without explicit storage class are treated as extern. We + // have to change the storage class this early to get the right DeclContext. + if (SC == SC_None && !DC->isRecord() && + hasParsedAttr(S, D, AttributeList::AT_DLLImport) && + !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) + SC = SC_Extern; + + DeclContext *OriginalDC = DC; + bool IsLocalExternDecl = SC == SC_Extern && + adjustContextForLocalExternDecl(DC); + if (SCSpec == DeclSpec::SCS_mutable) { // mutable can only appear on non-static class members, so it's always // an error here @@ -5988,32 +6018,6 @@ } } - if (getLangOpts().OpenCL) { - // OpenCL v1.2 s6.9.b p4: - // The sampler type cannot be used with the __local and __global address - // space qualifiers. - if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_local || - R.getAddressSpace() == LangAS::opencl_global)) { - Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); - } - - // OpenCL 1.2 spec, p6.9 r: - // The event type cannot be used to declare a program scope variable. - // The event type cannot be used with the __local, __constant and __global - // address space qualifiers. - if (R->isEventT()) { - if (S->getParent() == nullptr) { - Diag(D.getLocStart(), diag::err_event_t_global_var); - D.setInvalidType(); - } - - if (R.getAddressSpace()) { - Diag(D.getLocStart(), diag::err_event_t_addr_space_qual); - D.setInvalidType(); - } - } - } - bool IsExplicitSpecialization = false; bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; Index: test/SemaOpenCL/event_t.cl =================================================================== --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}} +event_t glb_evt; // expected-error {{the '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}} Index: test/SemaOpenCL/invalid-clk-events-cl2.0.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/invalid-clk-events-cl2.0.cl @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 + +global clk_event_t ce; // expected-error {{the '__global clk_event_t' type cannot be used to declare a program scope variable}} Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl =================================================================== --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +global pipe int gp; // expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} +global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} @@ -20,3 +23,8 @@ typedef pipe int pipe_int_t; pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'read_only pipe int') is not allowed}} + +bool test_id_comprision(void) { + reserve_id_t id1, id2; + return (id1 == id2); // expected-error {{invalid operands to binary expression ('reserve_id_t' and 'reserve_id_t')}} +}