Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2163,6 +2163,13 @@ } else { Kind = CK_BitCast; } + } else if (SrcType->isPointerType() && DestType->isPointerType() && + SrcType->getAs() + ->getPointeeType() + .getAddressSpace() != DestType->getAs() + ->getPointeeType() + .getAddressSpace()) { + Kind = CK_AddressSpaceConversion; } else { Kind = CK_BitCast; } Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -3143,6 +3143,12 @@ = PreviousToQualsIncludeConst && ToQuals.hasConst(); } + // ToDo: Add more detailed control for implicit address space casting for + // OpenCL C++. + if (FromType.getAddressSpace() != ToType.getAddressSpace() && + !getLangOpts().OpenCLCPlusPlus) + return false; + // We are left with FromType and ToType being the pointee types // after unwrapping the original FromType and ToType the same number // of types. If we unwrapped any pointers, and if FromType and Index: test/CodeGenCXX/address-space-cast.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/address-space-cast.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s + +#define __private__ __attribute__((address_space(5))) + +void func_pchar(__private__ char* x); + +void test(char *gen_ptr) { + // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)* + // CHECK-NEXT: store i8 addrspace(5)* %[[cast]] + __private__ char* priv_ptr = (__private__ char*)gen_ptr; + + // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)* + // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]]) + func_pchar((__private__ char*)gen_ptr); +}