Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -7696,7 +7696,7 @@ def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; -// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions +// OpenCL v2.0 s6.13.6 - Builtin Pipe Functions def err_opencl_builtin_pipe_first_arg : Error< "first argument to %0 must be a pipe type">; def err_opencl_builtin_pipe_arg_num : Error< @@ -7706,7 +7706,8 @@ def err_opencl_builtin_pipe_invalid_access_modifier : Error< "invalid pipe access modifier (expecting %0)">; -// OpenCL Section 6.8.g +// OpenCL v1.1 s6.8.g - extern, static, auto, register is not supported +// OpenCL v1.2/2.0 s6.8 - auto, register is not supported def err_opencl_unknown_type_specifier : Error< "OpenCL does not support the '%0' %select{type qualifier|storage class specifier}1">; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -6611,9 +6611,12 @@ NewVD->setInvalidDecl(); return; } - // OpenCL v1.1 s6.5.2 and s6.5.3 no local or constant variables + // OpenCL v1.1 s6.5.2 and s6.5.3 - No local or constant variables // in functions. - if (T.getAddressSpace() == LangAS::opencl_constant || + // OpenCL v1.2 s6.8.p2 - Extern can be used for variables declared + // in functions. + if ((T.getAddressSpace() == LangAS::opencl_constant && + !NewVD->isLocalExternDecl()) || T.getAddressSpace() == LangAS::opencl_local) { FunctionDecl *FD = getCurFunctionDecl(); if (FD && !FD->hasAttr()) { Index: test/CodeGenOpenCL/extern.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCL/extern.cl @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -x cl -cl-std=CL1.2 -emit-llvm -ffake-address-space-map %s -o - | FileCheck %s + +// CHECK: @foo = external addrspace(3) constant float +extern constant float foo; + +kernel void test(global float* buf) { + buf[0] += foo; +} + +void test2(global float* buf) { +// CHECK: @bar = external addrspace(3) constant [0 x float] + extern constant float bar[]; + buf[0] += bar[0]; +} + Index: test/SemaOpenCL/extern.cl =================================================================== --- test/SemaOpenCL/extern.cl +++ test/SemaOpenCL/extern.cl @@ -1,9 +1,8 @@ -// RUN: %clang_cc1 -x cl -cl-std=CL1.2 -emit-llvm -ffake-address-space-map %s -o - -verify | FileCheck %s -// expected-no-diagnostics +// RUN: %clang_cc1 -x cl -emit-llvm -ffake-address-space-map %s -o - -verify -// CHECK: @foo = external addrspace(3) constant float -extern constant float foo; +extern constant float foo; // expected-error{{OpenCL does not support the 'extern' storage class specifier}} expected-error{{variable in constant address space must be initialized}} kernel void test(global float* buf) { - buf[0] += foo; + extern constant float bar[10]; // expected-error{{OpenCL does not support the 'extern' storage class specifier}} expected-error{{variable in constant address space must be initialized}} } +