Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7352,28 +7352,8 @@ return; } } - // OpenCL v1.2 s6.5 - All program scope variables must be declared in the - // __constant address space. - // 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. - if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() || - NewVD->hasExternalStorage()) { - if (!T->isSamplerT() && - !(T.getAddressSpace() == LangAS::opencl_constant || - (T.getAddressSpace() == LangAS::opencl_global && - getLangOpts().OpenCLVersion == 200))) { - int Scope = NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1; - if (getLangOpts().OpenCLVersion == 200) - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << Scope << "global or constant"; - else - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) - << Scope << "constant"; - NewVD->setInvalidDecl(); - return; - } - } else { + if (!NewVD->isFileVarDecl() && !NewVD->isStaticLocal() && + !NewVD->hasExternalStorage()) { if (T.getAddressSpace() == LangAS::opencl_global) { Diag(NewVD->getLocation(), diag::err_opencl_function_variable) << 1 /*is any function*/ << "global"; @@ -12161,8 +12141,39 @@ DiagnosedNonDeducedAuto = true; } } - } + // OpenCL v1.2 s6.5 - All program scope variables must be declared in + // the __constant address space. + // 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. + if (getLangOpts().OpenCL) { + if (VarDecl *NewVD = dyn_cast(D)) { + if (!D->isInvalidDecl()) { + QualType T = NewVD->getType(); + if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() || + NewVD->hasExternalStorage()) { + if (!T->isSamplerT() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + int Scope = + NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1; + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), + diag::err_opencl_global_invalid_addr_space) + << Scope << "global or constant"; + else + Diag(NewVD->getLocation(), + diag::err_opencl_global_invalid_addr_space) + << Scope << "constant"; + NewVD->setInvalidDecl(); + } + } + } + } + } + } Decls.push_back(D); } } Index: test/SemaOpenCL/storageclass-cl20.cl =================================================================== --- test/SemaOpenCL/storageclass-cl20.cl +++ test/SemaOpenCL/storageclass-cl20.cl @@ -2,12 +2,12 @@ int G2 = 0; global int G3 = 0; -local int G4 = 0; // expected-error{{program scope variable must reside in global or constant address space}} +local int G4 = 0; // expected-error{{'__local' variable cannot have an initializer}} static float g_implicit_static_var = 0; static constant float g_constant_static_var = 0; static global float g_global_static_var = 0; -static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}} +static local float g_local_static_var = 0; // expected-error {{'__local' variable cannot have an initializer}} static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}} static generic float g_generic_static_var = 0; // expected-error {{program scope variable must reside in global or constant address space}} @@ -28,7 +28,7 @@ static float l_implicit_static_var = 0; static constant float l_constant_static_var = 0; static global float l_global_static_var = 0; - static local float l_local_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}} + static local float l_local_static_var = 0; // expected-error {{'__local' variable cannot have an initializer}} static private float l_private_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}} static generic float l_generic_static_var = 0; // expected-error {{static local variable must reside in global or constant address space}} Index: test/SemaOpenCL/storageclass.cl =================================================================== --- test/SemaOpenCL/storageclass.cl +++ test/SemaOpenCL/storageclass.cl @@ -4,11 +4,12 @@ constant int G2 = 0; int G3 = 0; // expected-error{{program scope variable must reside in constant address space}} global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}} +int G5, G6; // expected-error 2 {{program scope variable must reside in constant address space}} static float g_implicit_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} static constant float g_constant_static_var = 0; static global float g_global_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} -static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} +static local float g_local_static_var = 0; // expected-error {{'__local' variable cannot have an initializer}} static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} static generic float g_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}} Index: test/SemaOpenCLCXX/invalid-qualifier.cl =================================================================== --- /dev/null +++ test/SemaOpenCLCXX/invalid-qualifier.cl @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -fsyntax-only -verify +// RUN: not %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -fsyntax-only 2>&1 | FileCheck %s + +// Use FileCheck to check that "program scope variable must reside ..." is not +// the first diagnostic reported. + +int f1(global int *p) {} +// expected-error@-1{{use of undeclared identifier 'global'}} +// expected-error@-2{{expected ';' after top level declarator}} +// expected-error@-3{{program scope variable must reside in constant address space}} +// CHECK: use of undeclared identifier 'global' +// CHECK: program scope variable must reside in constant address space + +; // For parser recovery. + +int f2(local int *p) {} +// expected-error@-1{{use of undeclared identifier 'local'}} +// expected-error@-2{{expected ';' after top level declarator}} +// expected-error@-3{{program scope variable must reside in constant address space}} +// CHECK: use of undeclared identifier 'local' +// CHECK: program scope variable must reside in constant address space + +; // For parser recovery. + +int g(abcdef int q) {} +// expected-error@-1{{use of undeclared identifier 'abcdef'}} +// expected-error@-2{{expected ';' after top level declarator}} +// expected-error@-3{{program scope variable must reside in constant address space}} +// CHECK: use of undeclared identifier 'abcdef' +// CHECK: program scope variable must reside in constant address space + +; // For parser recovery.