diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2934,14 +2934,27 @@ } QualType ASTContext::removeAddrSpaceQualType(QualType T) const { + // If the type is not qualified with an address space, just return it + // immediately. + if (!T.hasAddressSpace()) + return T; + // If we are composing extended qualifiers together, merge together // into one ExtQuals node. QualifierCollector Quals; - const Type *TypeNode = Quals.strip(T); + const Type *TypeNode; - // If the qualifier doesn't have an address space just return it. - if (!Quals.hasAddressSpace()) - return T; + while (T.hasAddressSpace()) { + TypeNode = Quals.strip(T); + + // If the type no longer has an address space after stripping qualifiers, + // jump out. + if (!QualType(TypeNode, 0).hasAddressSpace()) + break; + + // There might be sugar in the way. Strip it and try again. + T = T.getSingleStepDesugaredType(*this); + } Quals.removeAddressSpace(); diff --git a/clang/test/CodeGenCXX/address-space-cast.cpp b/clang/test/CodeGenCXX/address-space-cast.cpp --- a/clang/test/CodeGenCXX/address-space-cast.cpp +++ b/clang/test/CodeGenCXX/address-space-cast.cpp @@ -6,6 +6,16 @@ void func_pvoid(__private__ void *x); void func_pint(__private__ int *x); +class Base { +}; + +class Derived : public Base { +}; + +void fn(Derived *p) { + __private__ Base *b = (__private__ Base *)p; +} + void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) { // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)* // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]