Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -2685,7 +2685,10 @@ } else if (VD->isConstexpr()) { // OK, we can read this variable. } else if (BaseType->isIntegralOrEnumerationType()) { - if (!BaseType.isConstQualified()) { + // In OpenCL if a variable is in constant address space it is a const value. + if (!(BaseType.isConstQualified() || + (Info.getLangOpts().OpenCL && + BaseType.getAddressSpace() == LangAS::opencl_constant))) { if (Info.getLangOpts().CPlusPlus) { Info.Diag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -2052,8 +2052,10 @@ } } Diagnoser; - return S.VerifyIntegerConstantExpression(ArraySize, &SizeVal, Diagnoser, - S.LangOpts.GNUMode).isInvalid(); + return S + .VerifyIntegerConstantExpression(ArraySize, &SizeVal, Diagnoser, + S.LangOpts.GNUMode || S.LangOpts.OpenCL) + .isInvalid(); } /// \brief Build an array type. Index: test/CodeGenOpenCL/vla.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCL/vla.cl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -DCL20 -o - %s | FileCheck %s --check-prefix=CL20 + +constant int sz0 = 5; +// CHECK: @sz0 = constant i32 5, align 4 +#ifdef CL20 +const global int sz1 = 16; +// CL20: @sz1 = constant i32 16, align 4 +const constant int sz2 = 8; +// CL20: @sz2 = constant i32 8, align 4 +// CL20: @testvla.vla2 = internal global [8 x i16] undef, align 16 +#endif + +kernel void testvla() +{ + int vla0[sz0]; +// CHECK: %vla0 = alloca [5 x i32], align 16 +#ifdef CL20 + char vla1[sz1]; +// CL20: %vla1 = alloca [16 x i8], align 16 + local short vla2[sz2]; +#endif +}