Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -6841,8 +6841,16 @@ // OpenCL v2.0 s6.9.q: // The clk_event_t and reserve_id_t types cannot be declared in program // scope. + // OpenCL v2.0 s6.5.1: + // Variables defined at program scope and static variables inside a function + // can also be declared in the global address space. They can be defined with + // any valid OpenCL C data type except for those in Other Built-in Data Types. + // OpenCL v3.0 s6.11.w: + // Program scope variables can be defined with any valid OpenCL C data type + // except for those in Other Built-in Data Types. if (NewVD->hasGlobalStorage() && !NewVD->isStaticLocal()) { - if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) { + if (R->isReserveIDT() || R->isClkEventT() || R->isEventT() || + R.getUnqualifiedType().getAsString() == "ndrange_t" || R->isQueueT()) { Se.Diag(NewVD->getLocation(), diag::err_invalid_type_for_program_scope_var) << R; Index: clang/test/SemaOpenCL/invalid-ndrange.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCL/invalid-ndrange.cl @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 + +typedef struct {int a;} ndrange_t; + +global ndrange_t qt; // expected-error {{the '__global ndrange_t' type cannot be used to declare a program scope variable}} Index: clang/test/SemaOpenCL/invalid-queue.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCL/invalid-queue.cl @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_device_enqueue + +global queue_t qt; // expected-error {{the '__global queue_t' type cannot be used to declare a program scope variable}}