diff options
-rw-r--r-- | lib/Sema/SemaCast.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/address-space-cast.cpp | 15 |
3 files changed, 32 insertions, 0 deletions
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 86633d6dd5..b3f6be4aec 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -1955,6 +1955,12 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, return Result.isUsable(); } +static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) { + return SrcType->isPointerType() && DestType->isPointerType() && + SrcType->getAs<PointerType>()->getPointeeType().getAddressSpace() != + DestType->getAs<PointerType>()->getPointeeType().getAddressSpace(); +} + static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, @@ -2198,6 +2204,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, } else { Kind = CK_BitCast; } + } else if (IsAddressSpaceConversion(SrcType, DestType)) { + Kind = CK_AddressSpaceConversion; } else { Kind = CK_BitCast; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 822c3c0c6b..390782b35e 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3150,6 +3150,15 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType, = PreviousToQualsIncludeConst && ToQuals.hasConst(); } + // Allows address space promotion by language rules implemented in + // Type::Qualifiers::isAddressSpaceSupersetOf. + Qualifiers FromQuals = FromType.getQualifiers(); + Qualifiers ToQuals = ToType.getQualifiers(); + if (!ToQuals.isAddressSpaceSupersetOf(FromQuals) && + !FromQuals.isAddressSpaceSupersetOf(ToQuals)) { + 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 diff --git a/test/CodeGenCXX/address-space-cast.cpp b/test/CodeGenCXX/address-space-cast.cpp new file mode 100644 index 0000000000..334a1a63e6 --- /dev/null +++ b/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_cast(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); +} |