[cfe-commits] r135036 - in /cfe/trunk: lib/CodeGen/CGClass.cpp lib/CodeGen/CGExprCXX.cpp test/CodeGenCXX/constructors.cpp
John McCall
rjmccall at apple.com
Wed Jul 13 00:37:11 PDT 2011
Author: rjmccall
Date: Wed Jul 13 02:37:11 2011
New Revision: 135036
URL: http://llvm.org/viewvc/llvm-project?rev=135036&view=rev
Log:
Arrays are permitted to be zero-length in some situations.
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/test/CodeGenCXX/constructors.cpp
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=135036&r1=135035&r2=135036&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jul 13 02:37:11 2011
@@ -1063,7 +1063,7 @@
///
/// \param ctor the constructor to call for each element
/// \param numElements the number of elements in the array;
-/// assumed to be non-zero
+/// may be zero
/// \param argBegin,argEnd the arguments to evaluate and pass to the
/// constructor
/// \param arrayBegin a T*, where T is the type constructed by ctor
@@ -1076,6 +1076,29 @@
CallExpr::const_arg_iterator argBegin,
CallExpr::const_arg_iterator argEnd,
bool zeroInitialize) {
+
+ // It's legal for numElements to be zero. This can happen both
+ // dynamically, because x can be zero in 'new A[x]', and statically,
+ // because of GCC extensions that permit zero-length arrays. There
+ // are probably legitimate places where we could assume that this
+ // doesn't happen, but it's not clear that it's worth it.
+ llvm::BranchInst *zeroCheckBranch = 0;
+
+ // Optimize for a constant count.
+ llvm::ConstantInt *constantCount
+ = dyn_cast<llvm::ConstantInt>(numElements);
+ if (constantCount) {
+ // Just skip out if the constant count is zero.
+ if (constantCount->isZero()) return;
+
+ // Otherwise, emit the check.
+ } else {
+ llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop");
+ llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty");
+ zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB);
+ EmitBlock(loopBB);
+ }
+
// Find the end of the array.
llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements,
"arrayctor.end");
@@ -1130,6 +1153,9 @@
llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont");
Builder.CreateCondBr(done, contBB, loopBB);
+ // Patch the earlier check to skip over the loop.
+ if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
+
EmitBlock(contBB);
}
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=135036&r1=135035&r2=135036&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Jul 13 02:37:11 2011
@@ -798,36 +798,10 @@
RequiresZeroInitialization = true;
}
- // It's legal for NumElements to be zero, but
- // EmitCXXAggrConstructorCall doesn't handle that, so we need to.
- llvm::BranchInst *br = 0;
-
- // Optimize for a constant count.
- llvm::ConstantInt *constantCount
- = dyn_cast<llvm::ConstantInt>(NumElements);
- if (constantCount) {
- // Just skip out if the constant count is zero.
- if (constantCount->isZero()) return;
-
- // Otherwise, emit the check.
- } else {
- llvm::BasicBlock *loopBB = CGF.createBasicBlock("new.ctorloop");
- llvm::Value *iszero = CGF.Builder.CreateIsNull(NumElements, "isempty");
- br = CGF.Builder.CreateCondBr(iszero, loopBB, loopBB);
- CGF.EmitBlock(loopBB);
- }
-
CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
E->constructor_arg_begin(),
E->constructor_arg_end(),
RequiresZeroInitialization);
-
- // Patch the earlier check to skip over the loop.
- if (br) {
- assert(CGF.Builder.GetInsertBlock()->empty());
- br->setSuccessor(0, CGF.Builder.GetInsertBlock());
- }
-
return;
} else if (E->getNumConstructorArgs() == 1 &&
isa<ImplicitValueInitExpr>(E->getConstructorArg(0))) {
Modified: cfe/trunk/test/CodeGenCXX/constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructors.cpp?rev=135036&r1=135035&r2=135036&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/constructors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/constructors.cpp Wed Jul 13 02:37:11 2011
@@ -104,3 +104,14 @@
C tmp = in;
}
}
+
+namespace test1 {
+ struct A { A(); void *ptr; };
+ struct B { B(); int x; A a[0]; };
+ B::B() {}
+ // CHECK: define void @_ZN5test11BC2Ev(
+ // CHECK: [[THIS:%.*]] = load [[B:%.*]]**
+ // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[B:%.*]]* [[THIS]], i32 0, i32 1
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [0 x {{%.*}}]* [[A]], i32 0, i32 0
+ // CHECK-NEXT: ret void
+}
More information about the cfe-commits
mailing list