]> granicus.if.org Git - clang/commitdiff
Check for null correctly for new expressions.
authorAnders Carlsson <andersca@mac.com>
Mon, 1 Jun 2009 00:05:16 +0000 (00:05 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 1 Jun 2009 00:05:16 +0000 (00:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72678 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/new.cpp

index 2cc9d0390f3c4ec3e1d255edd18a600096f158f4..32152f96bf0719761fafe396c71825ab6a3ab700 100644 (file)
@@ -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;
 }
 
index e3d1ec1df6c9ba6267b0c05d3c55f89eba5e1144..70ad269d24a2b2c9ce96655e387e48a40e3713e9 100644 (file)
@@ -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);
+}