Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -362,6 +362,13 @@ if (ExprTy == TypeTy) return E; + // If we are casting pointers, we need to make sure we deal with address + // spaces properly. + if (Kind == CK_NoOp && ExprTy->isPointerType() && TypeTy->isPointerType() && + ExprTy->getPointeeType().getAddressSpace() != + TypeTy->getPointeeType().getAddressSpace()) + Kind = CK_AddressSpaceConversion; + if (ImplicitCastExpr *ImpCast = dyn_cast(E)) { if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { ImpCast->setType(Ty); Index: test/Sema/address-space-cast.c =================================================================== --- /dev/null +++ test/Sema/address-space-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"; +}