Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -2308,12 +2308,7 @@ return getTargetAddressSpace(Q.getAddressSpace()); } - unsigned getTargetAddressSpace(unsigned AS) const { - if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count) - return AS; - else - return (*AddrSpaceMap)[AS - LangAS::Offset]; - } + unsigned getTargetAddressSpace(unsigned AS) const; /// Get target-dependent integer value for null pointer which is used for /// constant folding. @@ -2321,8 +2316,7 @@ bool addressSpaceMapManglingFor(unsigned AS) const { return AddrSpaceMapMangling || - AS < LangAS::Offset || - AS >= LangAS::Offset + LangAS::Count; + AS > LangAS::target_first; } private: Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -333,6 +333,13 @@ bool hasAddressSpace() const { return Mask & AddressSpaceMask; } unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; } + /// Get the address space value used in diagnostics. + unsigned getAddressSpacePrintValue() const { + unsigned AS = getAddressSpace(); + if (AS >= LangAS::target_first) + return AS - LangAS::target_first; + return AS; + } void setAddressSpace(unsigned space) { assert(space <= MaxAddressSpace); Mask = (Mask & ~AddressSpaceMask) Index: include/clang/Basic/AddressSpaces.h =================================================================== --- include/clang/Basic/AddressSpaces.h +++ include/clang/Basic/AddressSpaces.h @@ -22,12 +22,12 @@ /// \brief Defines the set of possible language-specific address spaces. /// -/// This uses a high starting offset so as not to conflict with any address -/// space used by a target. +/// This uses values above the language-specific address spaces to denote +/// the target-specific address spaces biased by target_first. enum ID { - Offset = 0x7FFF00, + Default = 0, - opencl_global = Offset, + opencl_global, opencl_local, opencl_constant, opencl_generic, @@ -36,8 +36,9 @@ cuda_constant, cuda_shared, - Last, - Count = Last-Offset + Count, + + target_first = Count }; /// The type of a lookup table which maps from language-specific address spaces Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2448,8 +2448,9 @@ "vector component access exceeds type %0">; def err_ext_vector_component_name_illegal : Error< "illegal vector component name '%0'">; -def err_attribute_address_space_negative : Error< - "address space is negative">; +def warn_attribute_address_space_negative : Warning< + "address space is negative">, + InGroup>; def err_attribute_address_space_too_high : Error< "address space is larger than the maximum supported (%0)">; def err_attribute_address_multiple_qualifiers : Error< Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -703,6 +703,7 @@ // The fake address space map must have a distinct entry for each // language-specific address space. static const unsigned FakeAddrSpaceMap[] = { + 0, // Default 1, // opencl_global 3, // opencl_local 2, // opencl_constant @@ -8725,7 +8726,8 @@ char *End; unsigned AddrSpace = strtoul(Str, &End, 10); if (End != Str && AddrSpace != 0) { - Type = Context.getAddrSpaceQualType(Type, AddrSpace); + Type = Context.getAddrSpaceQualType(Type, AddrSpace + + LangAS::target_first); Str = End; } if (c == '*') @@ -9544,6 +9546,18 @@ return getTargetInfo().getNullPointerValue(AS); } +unsigned ASTContext::getTargetAddressSpace(unsigned AS) const { + // For OpenCL, only function local variables are not explicitly marked with + // an address space in the AST, and these need to be the address space of + // alloca. + if (AS == LangAS::Default && LangOpts.OpenCL) + return getTargetInfo().getDataLayout().getAllocaAddrSpace(); + if (AS >= LangAS::target_first) + return AS - LangAS::target_first; + else + return (*AddrSpaceMap)[AS]; +} + // Explicitly instantiate this in case a Redeclarable is used from a TU that // doesn't include ASTContext.h template Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1653,14 +1653,22 @@ OS << "__local"; break; case LangAS::opencl_constant: + case LangAS::cuda_constant: OS << "__constant"; break; case LangAS::opencl_generic: OS << "__generic"; break; + case LangAS::cuda_device: + OS << "__device"; + break; + case LangAS::cuda_shared: + OS << "__shared"; + break; default: + assert(addrspace >= LangAS::target_first); OS << "__attribute__((address_space("; - OS << addrspace; + OS << addrspace - LangAS::target_first; OS << ")))"; } } Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1777,6 +1777,7 @@ }; static const unsigned NVPTXAddrSpaceMap[] = { + 0, // Default 1, // opencl_global 3, // opencl_local 4, // opencl_constant @@ -2031,6 +2032,7 @@ } static const LangAS::Map AMDGPUPrivateIsZeroMap = { + 4, // Default 1, // opencl_global 3, // opencl_local 2, // opencl_constant @@ -2040,6 +2042,7 @@ 3 // cuda_shared }; static const LangAS::Map AMDGPUGenericIsZeroMap = { + 0, // Default 1, // opencl_global 3, // opencl_local 4, // opencl_constant @@ -2064,7 +2067,7 @@ static const char *const DataLayoutStringSIGenericIsZero = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" - "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; + "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"; class AMDGPUTargetInfo final : public TargetInfo { static const Builtin::Info BuiltinInfo[]; @@ -2139,6 +2142,7 @@ (IsGenericZero ? DataLayoutStringSIGenericIsZero : DataLayoutStringSIPrivateIsZero) : DataLayoutStringR600); + assert(DataLayout->getAllocaAddrSpace() == AS.Private); AddrSpaceMap = IsGenericZero ? &AMDGPUGenericIsZeroMap : &AMDGPUPrivateIsZeroMap; @@ -7408,6 +7412,7 @@ // publicly available in http://tce.cs.tut.fi static const unsigned TCEOpenCLAddrSpaceMap[] = { + 0, // Default 3, // opencl_global 4, // opencl_local 5, // opencl_constant @@ -8374,6 +8379,7 @@ }; static const unsigned SPIRAddrSpaceMap[] = { + 4, // Default 1, // opencl_global 3, // opencl_local 2, // opencl_constant Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1193,7 +1193,8 @@ CGM.getContext() .toCharUnitsFromBits(TI.getSuitableAlign()) .getQuantity(); - AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); + AllocaInst *AI = Builder.CreateAlloca(CGM.getDataLayout(), + Builder.getInt8Ty(), Size); AI->setAlignment(SuitableAlignmentInBytes); return RValue::get(AI); } @@ -1205,7 +1206,8 @@ unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue(); unsigned AlignmentInBytes = CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity(); - AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); + AllocaInst *AI = Builder.CreateAlloca(CGM.getDataLayout(), + Builder.getInt8Ty(), Size); AI->setAlignment(AlignmentInBytes); return RValue::get(AI); } Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -3715,7 +3715,8 @@ llvm::AllocaInst *AI; if (IP) { IP = IP->getNextNode(); - AI = new llvm::AllocaInst(ArgStruct, "argmem", IP); + AI = new llvm::AllocaInst(ArgStruct, + CGM.getDataLayout().getAllocaAddrSpace(), "argmem", IP); } else { AI = CreateTempAlloca(ArgStruct, "argmem"); } Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -1096,7 +1096,8 @@ llvm::Type *llvmTy = ConvertTypeForMem(elementType); // Allocate memory for the array. - llvm::AllocaInst *vla = Builder.CreateAlloca(llvmTy, elementCount, "vla"); + llvm::AllocaInst *vla = Builder.CreateAlloca(CGM.getDataLayout(), + llvmTy, elementCount, "vla"); vla->setAlignment(alignment.getQuantity()); address = Address(vla, alignment); Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -71,7 +71,8 @@ /// block. llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, const Twine &Name) { - return new llvm::AllocaInst(Ty, nullptr, Name, AllocaInsertPt); + return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(), + nullptr, Name, AllocaInsertPt); } /// CreateDefaultAlignTempAlloca - This creates an alloca with the Index: lib/CodeGen/CGObjCGNU.cpp =================================================================== --- lib/CodeGen/CGObjCGNU.cpp +++ lib/CodeGen/CGObjCGNU.cpp @@ -1330,8 +1330,8 @@ Receiver->getType(), IdTy, nullptr); // FIXME: Is this really supposed to be a dynamic alloca? - Address ObjCSuper = Address(Builder.CreateAlloca(ObjCSuperTy), - CGF.getPointerAlign()); + Address ObjCSuper = Address(Builder.CreateAlloca(CGM.getDataLayout(), + ObjCSuperTy), CGF.getPointerAlign()); Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero())); Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2048,7 +2048,8 @@ else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; - else if (unsigned AddressSpace = AllocType.getAddressSpace()) + else if (unsigned AddressSpace = AllocType.getQualifiers(). + getAddressSpacePrintValue()) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AddressSpace; else if (getLangOpts().ObjCAutoRefCount) { @@ -3117,10 +3118,12 @@ QualType Pointee = Type->getAs()->getPointeeType(); QualType PointeeElem = Context.getBaseElementType(Pointee); - if (unsigned AddressSpace = Pointee.getAddressSpace()) + if (unsigned AddressSpace = Pointee.getQualifiers(). + getAddressSpacePrintValue()) return Diag(Ex.get()->getLocStart(), diag::err_address_space_qualified_delete) - << Pointee.getUnqualifiedType() << AddressSpace; + << Pointee.getUnqualifiedType() + << AddressSpace; CXXRecordDecl *PointeeRD = nullptr; if (Pointee->isVoidType() && !isSFINAEContext()) { Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -9494,7 +9494,8 @@ << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy - << FromQs.getAddressSpace() << ToQs.getAddressSpace() + << FromQs.getAddressSpacePrintValue() + << ToQs.getAddressSpacePrintValue() << (unsigned) isObjectArgument << I+1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5508,7 +5508,7 @@ return; } Expr *ASArgExpr = static_cast(Attr.getArgAsExpr(0)); - llvm::APSInt addrSpace(32); + llvm::APSInt addrSpace(32, false); if (ASArgExpr->isTypeDependent() || ASArgExpr->isValueDependent() || !ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) @@ -5521,21 +5521,21 @@ // Bounds checking. if (addrSpace.isSigned()) { if (addrSpace.isNegative()) { - S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative) + S.Diag(Attr.getLoc(), diag::warn_attribute_address_space_negative) << ASArgExpr->getSourceRange(); - Attr.setInvalid(); - return; } - addrSpace.setIsSigned(false); } - llvm::APSInt max(addrSpace.getBitWidth()); - max = Qualifiers::MaxAddressSpace; + llvm::APSInt max(addrSpace.getBitWidth(), false); + max = Qualifiers::MaxAddressSpace - LangAS::target_first; if (addrSpace > max) { S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high) - << int(Qualifiers::MaxAddressSpace) << ASArgExpr->getSourceRange(); + << (unsigned)max.getZExtValue() << ASArgExpr->getSourceRange(); Attr.setInvalid(); return; } + llvm::APSInt Offset(addrSpace.getBitWidth(), false); + Offset = LangAS::target_first; + addrSpace += Offset; ASIdx = static_cast(addrSpace.getZExtValue()); } else { // The keyword-based type attributes imply which address space to use. Index: test/CodeGenOpenCL/address-space-constant-initializers.cl =================================================================== --- test/CodeGenOpenCL/address-space-constant-initializers.cl +++ test/CodeGenOpenCL/address-space-constant-initializers.cl @@ -1,4 +1,6 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple amdgcn-amd-amdhsa-opencl -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s typedef struct { int i; @@ -13,6 +15,8 @@ // CHECK: %struct.ConstantArrayPointerStruct = type { float addrspace(2)* } // CHECK: addrspace(2) constant %struct.ConstantArrayPointerStruct { float addrspace(2)* bitcast (i8 addrspace(2)* getelementptr (i8, i8 addrspace(2)* bitcast (%struct.ArrayStruct addrspace(2)* @constant_array_struct to i8 addrspace(2)*), i64 4) to float addrspace(2)*) } +// GIZ: %struct.ConstantArrayPointerStruct = type { float addrspace(4)* } +// GIZ: addrspace(4) constant %struct.ConstantArrayPointerStruct { float addrspace(4)* bitcast (i8 addrspace(4)* getelementptr (i8, i8 addrspace(4)* bitcast (%struct.ArrayStruct addrspace(4)* @constant_array_struct to i8 addrspace(4)*), i64 4) to float addrspace(4)*) } // Bug 18567 __constant ConstantArrayPointerStruct constant_array_pointer_struct = { &constant_array_struct.f Index: test/CodeGenOpenCL/address-spaces.cl =================================================================== --- test/CodeGenOpenCL/address-spaces.cl +++ test/CodeGenOpenCL/address-spaces.cl @@ -1,7 +1,12 @@ -// RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefix=CL20 - -// CHECK: i32* %arg +// RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR +// RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-opencl -emit-llvm -o - | FileCheck --check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-opencl -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,GIZ +// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-amdgizcl -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20GIZ + +// SPIR: i32* %arg +// GIZ: i32 addrspace(5)* %arg void f__p(__private int *arg) {} // CHECK: i32 addrspace(1)* %arg @@ -10,10 +15,12 @@ // CHECK: i32 addrspace(3)* %arg void f__l(__local int *arg) {} -// CHECK: i32 addrspace(2)* %arg +// SPIR: i32 addrspace(2)* %arg +// GIZ: i32 addrspace(4)* %arg void f__c(__constant int *arg) {} -// CHECK: i32* %arg +// SPIR: i32* %arg +// GIZ: i32 addrspace(5)* %arg void fp(private int *arg) {} // CHECK: i32 addrspace(1)* %arg @@ -22,23 +29,29 @@ // CHECK: i32 addrspace(3)* %arg void fl(local int *arg) {} -// CHECK: i32 addrspace(2)* %arg +// SPIR: i32 addrspace(2)* %arg +// GIZ: i32 addrspace(4)* %arg void fc(constant int *arg) {} #ifdef CL20 int i; // CL20-DAG: @i = common addrspace(1) global i32 0 int *ptr; -// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null +// CL20SPIR-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null +// CL20GIZ-DAG: @ptr = common addrspace(1) global i32* null #endif -// CHECK: i32* %arg -// CL20-DAG: i32 addrspace(4)* %arg +// SPIR: i32* %arg +// GIZ: i32 addrspace(5)* %arg +// CL20SPIR-DAG: i32 addrspace(4)* %arg +// CL20GIZ-DAG: i32* %arg void f(int *arg) { int i; -// CHECK: %i = alloca i32, -// CL20-DAG: %i = alloca i32, +// SPIR: %i = alloca i32, +// GIZ: %i = alloca i32{{.*}}addrspace(5) +// CL20SPIR-DAG: %i = alloca i32, +// CL20GIZ-DAG: %i = alloca i32{{.*}}addrspace(5) #ifdef CL20 static int ii; Index: test/CodeGenOpenCL/amdgpu-env-amdgiz.cl =================================================================== --- test/CodeGenOpenCL/amdgpu-env-amdgiz.cl +++ test/CodeGenOpenCL/amdgpu-env-amdgiz.cl @@ -4,6 +4,6 @@ // RUN: %clang_cc1 %s -O0 -triple amdgcn---amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s // CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" -// GIZ: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" +// GIZ: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5" void foo(void) {} Index: test/CodeGenOpenCL/vla.cl =================================================================== --- test/CodeGenOpenCL/vla.cl +++ test/CodeGenOpenCL/vla.cl @@ -1,18 +1,26 @@ -// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-opencl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-amdgizcl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,GIZ %s constant int sz0 = 5; -// CHECK: @sz0 = addrspace(2) constant i32 5 +// SPIR: @sz0 = addrspace(2) constant i32 5 +// GIZ: @sz0 = addrspace(4) constant i32 5 const global int sz1 = 16; // CHECK: @sz1 = addrspace(1) constant i32 16 const constant int sz2 = 8; -// CHECK: @sz2 = addrspace(2) constant i32 8 +// SPIR: @sz2 = addrspace(2) constant i32 8 +// GIZ: @sz2 = addrspace(4) constant i32 8 // CHECK: @testvla.vla2 = internal addrspace(3) global [8 x i16] undef kernel void testvla() { int vla0[sz0]; -// CHECK: %vla0 = alloca [5 x i32] +// SPIR: %vla0 = alloca [5 x i32] +// SPIR-NOT: %vla0 = alloca [5 x i32]{{.*}}addrspace +// GIZ: %vla0 = alloca [5 x i32]{{.*}}addrspace(5) char vla1[sz1]; -// CHECK: %vla1 = alloca [16 x i8] +// SPIR: %vla1 = alloca [16 x i8] +// SPIR-NOT: %vla1 = alloca [16 x i8]{{.*}}addrspace +// GIZ: %vla1 = alloca [16 x i8]{{.*}}addrspace(5) local short vla2[sz2]; } Index: test/Sema/address_spaces.c =================================================================== --- test/Sema/address_spaces.c +++ test/Sema/address_spaces.c @@ -19,8 +19,8 @@ _AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}} _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} - __attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}} - __attribute__((address_space(0x7FFFFF))) int *_boundsB; + __attribute__((address_space(-1))) int *_boundsA; // expected-warning {{address space is negative}} + __attribute__((address_space(0x7FFFFF))) int *_boundsB; // expected-error {{address space is larger than the maximum supported}} __attribute__((address_space(0x1000000))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}} // chosen specifically to overflow 32 bits and come out reasonable __attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}} Index: test/Sema/invalid-assignment-constant-address-space.c =================================================================== --- test/Sema/invalid-assignment-constant-address-space.c +++ test/Sema/invalid-assignment-constant-address-space.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -#define OPENCL_CONSTANT 8388354 -int __attribute__((address_space(OPENCL_CONSTANT))) c[3] = {0}; +#define OPENCL_CONSTANT -5 +int __attribute__((address_space(OPENCL_CONSTANT))) c[3] = {0}; //expected-warning{{address space is negative}} void foo() { c[0] = 1; //expected-error{{read-only variable is not assignable}}