summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp15
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();