[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