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 | ca50119a31d335b46dcc9940f6f6fd6cabe8ea33 (patch) | |
| tree | 1d11fc75af29b8aeeae18f916a749d6488d199d5 /clang | |
| parent | cba81fc4de83b0ffa430c94b9ad88b8cf7bb1622 (diff) | |
| download | bcm5719-llvm-ca50119a31d335b46dcc9940f6f6fd6cabe8ea33.tar.gz bcm5719-llvm-ca50119a31d335b46dcc9940f6f6fd6cabe8ea33.zip | |
Check for null correctly for new expressions.
llvm-svn: 72678
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 36 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/new.cpp | 5 |
2 files changed, 37 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 2cc9d0390f3..32152f96bf0 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/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; } diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp index e3d1ec1df6c..70ad269d24a 100644 --- a/clang/test/CodeGenCXX/new.cpp +++ b/clang/test/CodeGenCXX/new.cpp @@ -45,3 +45,8 @@ void t5() { // RUN: grep "call void @_ZN2T2C1Eii" %t | count 1 T2 *t2 = new T2(10, 10); } + +int *t6() { + // Null check. + return new (0) int(10); +} |

