[cfe-commits] r127147 - in /cfe/trunk: lib/CodeGen/CGExprCXX.cpp test/CodeGenCXX/exceptions.cpp

John McCall rjmccall at apple.com
Sun Mar 6 17:52:56 PST 2011


Author: rjmccall
Date: Sun Mar  6 19:52:56 2011
New Revision: 127147

URL: http://llvm.org/viewvc/llvm-project?rev=127147&view=rev
Log:
An operator new with an empty exception specifier returns null on a bad
allocation and therefore requires a null-check.  We were doing that, but
we weren't treating the new-initializer as being conditionally executed,
which means it was possible to get ill-formed IR as in PR9298.


Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/exceptions.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=127147&r1=127146&r2=127147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Sun Mar  6 19:52:56 2011
@@ -993,6 +993,10 @@
   llvm::Value *NewPtr = RV.getScalarVal();
   unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
 
+  // The null-check means that the initializer is conditionally
+  // evaluated.
+  ConditionalEvaluation conditional(*this);
+
   if (NullCheckResult) {
     NullCheckSource = Builder.GetInsertBlock();
     NewNotNull = createBasicBlock("new.notnull");
@@ -1001,6 +1005,8 @@
     llvm::Value *IsNull = Builder.CreateIsNull(NewPtr, "new.isnull");
     Builder.CreateCondBr(IsNull, NewEnd, NewNotNull);
     EmitBlock(NewNotNull);
+
+    conditional.begin(*this);
   }
   
   assert((AllocSize == AllocSizeWithoutCookie) ==
@@ -1042,6 +1048,8 @@
     DeactivateCleanupBlock(CallOperatorDelete);
   
   if (NullCheckResult) {
+    conditional.end(*this);
+
     Builder.CreateBr(NewEnd);
     llvm::BasicBlock *NotNullSource = Builder.GetInsertBlock();
     EmitBlock(NewEnd);

Modified: cfe/trunk/test/CodeGenCXX/exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions.cpp?rev=127147&r1=127146&r2=127147&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions.cpp Sun Mar  6 19:52:56 2011
@@ -305,3 +305,21 @@
     }
   }
 }
+
+// PR9298
+namespace test7 {
+  struct A { A(); ~A(); };
+  struct B {
+    // The throw() operator means that a bad allocation is signalled
+    // with a null return, which means that the initializer is
+    // evaluated conditionally.
+    static void *operator new(size_t size) throw();
+    B(const A&, B*);
+    ~B();
+  };
+
+  // Just make sure the result passes verification.
+  B *test() {
+    return new B(A(), new B(A(), 0));
+  }
+}





More information about the cfe-commits mailing list