From c211c6c8844a46f8ac795ef7998b81772bc99103 Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Tue, 29 Nov 2016 10:21:40 +0000 Subject: [PATCH] [OpenCL] Prohibit using reserve_id_t in program scope. Patch by Egor Churaev (echuraev). Reviewers: Anastasia Subscribers: cfe-commits, yaxunl, bader Differential Revision: https://reviews.llvm.org/D27099 llvm-svn: 288126 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 +- clang/lib/Sema/SemaDecl.cpp | 105 +++++++++++----------- clang/test/SemaOpenCL/event_t.cl | 2 +- clang/test/SemaOpenCL/invalid-clk-events-cl2.0.cl | 3 + clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl | 8 ++ 5 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 clang/test/SemaOpenCL/invalid-clk-events-cl2.0.cl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index beba4a3..8843100 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8075,8 +8075,6 @@ def note_within_field_of_type : Note< "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< @@ -8589,6 +8587,8 @@ def note_related_result_type_inferred : Note< 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">; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fb2468f..58776e8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5909,32 +5909,31 @@ NamedDecl *Sema::ActOnVariableDeclarator( 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 v1.2 s6.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 +5953,40 @@ NamedDecl *Sema::ActOnVariableDeclarator( 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 v1.2 s6.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 +6019,6 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } - 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; diff --git a/clang/test/SemaOpenCL/event_t.cl b/clang/test/SemaOpenCL/event_t.cl index 990c063..e7daf88 100644 --- a/clang/test/SemaOpenCL/event_t.cl +++ b/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 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}} diff --git a/clang/test/SemaOpenCL/invalid-clk-events-cl2.0.cl b/clang/test/SemaOpenCL/invalid-clk-events-cl2.0.cl new file mode 100644 index 0000000..8c8e1c6 --- /dev/null +++ b/clang/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}} diff --git a/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl b/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl index 96874a0..c425bc9 100644 --- a/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ b/clang/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 @@ void test5(pipe int p) { 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')}} +} -- 2.7.4