diff options
author | Anders Carlsson <andersca@mac.com> | 2009-06-01 00:05:16 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-06-01 00:05:16 +0000 |
commit | f11085398dc27c0010663c711d4a10113e41d70f (patch) | |
tree | 052f9782b781119caa5840ea97999cfab161c134 /lib/CodeGen/CGCXX.cpp | |
parent | d3fd6bad1249d3f34d71b73e2333fab0db51cce4 (diff) |
Check for null correctly for new expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72678 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 2cc9d0390f..32152f96bf 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -292,13 +292,27 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && !(AllocType->isPODType() && !E->hasInitializer()); + llvm::BasicBlock *NewNull = 0; + llvm::BasicBlock *NewNotNull = 0; + llvm::BasicBlock *NewEnd = 0; + + llvm::Value *NewPtr = RV.getScalarVal(); + if (NullCheckResult) { - ErrorUnsupported(E, "new expr that needs to be null checked"); - return llvm::UndefValue::get(ConvertType(E->getType())); + NewNull = createBasicBlock("new.null"); + NewNotNull = createBasicBlock("new.notnull"); + NewEnd = createBasicBlock("new.end"); + + llvm::Value *IsNull = + Builder.CreateICmpEQ(NewPtr, + llvm::Constant::getNullValue(NewPtr->getType()), + "isnull"); + + Builder.CreateCondBr(IsNull, NewNull, NewNotNull); + EmitBlock(NewNotNull); } - llvm::Value *NewPtr = - Builder.CreateBitCast(RV.getScalarVal(), ConvertType(E->getType())); + NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); if (AllocType->isPODType()) { if (E->hasInitializer()) { @@ -323,6 +337,20 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { E->constructor_arg_end()); } + if (NullCheckResult) { + Builder.CreateBr(NewEnd); + EmitBlock(NewNull); + Builder.CreateBr(NewEnd); + EmitBlock(NewEnd); + + llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); + PHI->reserveOperandSpace(2); + PHI->addIncoming(NewPtr, NewNotNull); + PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull); + + NewPtr = PHI; + } + return NewPtr; } |