diff options
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index f3a5387c58..26e327a41a 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1299,7 +1299,18 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { case CK_AnyPointerToBlockPointerCast: case CK_BitCast: { Value *Src = Visit(const_cast<Expr*>(E)); - return Builder.CreateBitCast(Src, ConvertType(DestTy)); + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = ConvertType(DestTy); + if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) { + llvm::Type *MidTy = CGF.CGM.getDataLayout().getIntPtrType(SrcTy); + return Builder.CreateIntToPtr(Builder.CreatePtrToInt(Src, MidTy), DstTy); + } + return Builder.CreateBitCast(Src, DstTy); + } + case CK_AddressSpaceConversion: { + Value *Src = Visit(const_cast<Expr*>(E)); + return Builder.CreateAddrSpaceCast(Src, ConvertType(DestTy)); } case CK_AtomicToNonAtomic: case CK_NonAtomicToAtomic: @@ -1360,7 +1371,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // Make sure the array decay ends up being the right type. This matters if // the array type was of an incomplete type. - return CGF.Builder.CreateBitCast(V, ConvertType(CE->getType())); + return CGF.Builder.CreatePointerCast(V, ConvertType(CE->getType())); } case CK_FunctionToPointerDecay: return EmitLValue(E).getAddress(); |