diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4095,9 +4095,26 @@ << From->getSourceRange(); } + // Defer address space conversion to the third conversion. + QualType FromPteeType = From->getType()->getPointeeType(); + QualType ToPteeType = ToType->getPointeeType(); + QualType NewToType = ToType; + if (!FromPteeType.isNull() && !ToPteeType.isNull() && + FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) { + NewToType = Context.removeAddrSpaceQualType(ToPteeType); + NewToType = Context.getAddrSpaceQualType(NewToType, + FromPteeType.getAddressSpace()); + if (ToType->isObjCObjectPointerType()) + NewToType = Context.getObjCObjectPointerType(NewToType); + else if (ToType->isBlockPointerType()) + NewToType = Context.getBlockPointerType(NewToType); + else + NewToType = Context.getPointerType(NewToType); + } + CastKind Kind; CXXCastPath BasePath; - if (CheckPointerConversion(From, ToType, Kind, BasePath, CStyle)) + if (CheckPointerConversion(From, NewToType, Kind, BasePath, CStyle)) return ExprError(); // Make sure we extend blocks if necessary. @@ -4108,8 +4125,8 @@ From = E.get(); } if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) - CheckObjCConversion(SourceRange(), ToType, From, CCK); - From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) + CheckObjCConversion(SourceRange(), NewToType, From, CCK); + From = ImpCastExprToType(From, NewToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; } diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl --- a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl +++ b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl @@ -69,3 +69,14 @@ // CHECK: bitcast i8 addrspace(4)* %add.ptr1 to %class.B2 addrspace(4)* // CHECK: call {{.*}} @_ZNU3AS42B26getRefEv } + +// Implicit conversion of derived to base. + +void functionWithBaseArgPtr(class B2 *b) {} +void functionWithBaseArgRef(class B2 &b) {} + +void pr43145_4() { + Derived d; + functionWithBaseArgPtr(&d); + functionWithBaseArgRef(d); +}