aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-05 06:12:26 +0000
committerMike Stump <mrs@apple.com>2009-11-05 06:12:26 +0000
commit7c276b84d6881df18c847b036fe3c95d94d9b5b3 (patch)
tree3287e60b2dc4df7f7156706bd6077682dec15066 /lib/CodeGen/CGCXX.cpp
parent99faefdac32eda8cf0d6db722588a76caa3add22 (diff)
Refine covariant return value adjustments for thunks when null
pointers are returned. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86120 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index d4adbad1e4..fd90dc06d5 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -811,7 +811,25 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
Callee, CallArgs, MD);
if (nv_r || v_r) {
// Do the return result adjustment.
- RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r));
+ llvm::BasicBlock *NonZeroBlock = createBasicBlock();
+ llvm::BasicBlock *ZeroBlock = createBasicBlock();
+ llvm::BasicBlock *ContBlock = createBasicBlock();
+
+ const llvm::Type *Ty = RV.getScalarVal()->getType();
+ llvm::Value *Zero = llvm::Constant::getNullValue(Ty);
+ Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero),
+ NonZeroBlock, ZeroBlock);
+ EmitBlock(NonZeroBlock);
+ llvm::Value *NZ = DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r);
+ EmitBranch(ContBlock);
+ EmitBlock(ZeroBlock);
+ llvm::Value *Z = RV.getScalarVal();
+ EmitBlock(ContBlock);
+ llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty);
+ RVOrZero->reserveOperandSpace(2);
+ RVOrZero->addIncoming(NZ, NonZeroBlock);
+ RVOrZero->addIncoming(Z, ZeroBlock);
+ RV = RValue::get(RVOrZero);
}
if (!ResultType->isVoidType())