Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -362,6 +362,14 @@ if (ExprTy == TypeTy) return E; + // In the event an address space cast is requested, the kind passed from the + // caller should no be CK_NoOp. + assert((Kind != CK_NoOp || + !(ExprTy->isPointerType() && TypeTy->isPointerType() && + ExprTy->getPointeeType().getAddressSpace() != + TypeTy->getPointeeType().getAddressSpace())) && + "NoOp is not a valid kind for and address cast"); + if (ImplicitCastExpr *ImpCast = dyn_cast(E)) { if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { ImpCast->setType(Ty); Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -2103,6 +2103,15 @@ return; } + // If we are casting pointers, we need to check whether this refers to an + // address cast. + if (DestType->isPointerType() && SrcExpr.get()->getType()->isPointerType() && + DestType->getPointeeType().getAddressSpace() != + SrcExpr.get()->getType().getAddressSpace()) { + Kind = CK_AddressSpaceConversion; + return; + } + // C++ [expr.cast]p5: The conversions performed by // - a const_cast, // - a static_cast, Index: test/CodeGen/address-space-explicit-cast.c =================================================================== --- /dev/null +++ test/CodeGen/address-space-explicit-cast.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm -o - -x c %s | FileCheck -check-prefix=CHECK %s +// RUN: %clang_cc1 -emit-llvm -o - -x c++ %s | FileCheck -check-prefix=CHECK-CXX %s + +typedef __attribute__((address_space(1))) char *AddrSpaceCharType; + +// CHECK-LABEL: @foo() +// CHECK-CXX-LABEL: @_Z3foov() +void foo() { + // CHECK: %p = alloca i8 addrspace(1)* + // CHECK-CXX: %p = alloca i8 addrspace(1)* + AddrSpaceCharType p; + + // CHECK: store i8 addrspace(1)* addrspacecast ({{.*}} to i8 addrspace(1)*), i8 addrspace(1)** %p + // CHECK-CXX: store i8 addrspace(1)* addrspacecast ({{.*}} to i8 addrspace(1)*), i8 addrspace(1)** %p + p = (AddrSpaceCharType) "a"; +}