aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-11-24 18:43:52 +0000
committerAnders Carlsson <andersca@mac.com>2009-11-24 18:43:52 +0000
commit5d4d946ec2d88696fd8422aeb64dc29688e6a2c1 (patch)
treed8fcf6c964a4873fc549e7a65104815baad0871a /lib/CodeGen/CGCXX.cpp
parent80ad16f4b2b350ddbaae21a52975e63df5aafc2c (diff)
Handle cases where we're constructing an array of objects and the constructor has default arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89783 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index b7670dfb45..19cc04bace 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -463,20 +463,25 @@ llvm::Value *CodeGenFunction::LoadCXXThis() {
/// It is assumed that all relevant checks have been made by the caller.
void
CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
- const ConstantArrayType *ArrayTy,
- llvm::Value *ArrayPtr) {
+ const ConstantArrayType *ArrayTy,
+ llvm::Value *ArrayPtr,
+ CallExpr::const_arg_iterator ArgBeg,
+ CallExpr::const_arg_iterator ArgEnd) {
+
const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
llvm::Value * NumElements =
llvm::ConstantInt::get(SizeTy,
getContext().getConstantArrayElementCount(ArrayTy));
- EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr);
+ EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
}
void
CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
- llvm::Value *NumElements,
- llvm::Value *ArrayPtr) {
+ llvm::Value *NumElements,
+ llvm::Value *ArrayPtr,
+ CallExpr::const_arg_iterator ArgBeg,
+ CallExpr::const_arg_iterator ArgEnd) {
const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
// Create a temporary for the loop index and initialize it with 0.
@@ -506,8 +511,24 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
Counter = Builder.CreateLoad(IndexPtr);
llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter,
"arrayidx");
- EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0);
+ // C++ [class.temporary]p4:
+ // There are two contexts in which temporaries are destroyed at a different
+ // point than the end of the full- expression. The first context is when a
+ // default constructor is called to initialize an element of an array.
+ // If the constructor has one or more default arguments, the destruction of
+ // every temporary created in a default argument expression is sequenced
+ // before the construction of the next array element, if any.
+
+ // Keep track of the current number of live temporaries.
+ unsigned OldNumLiveTemporaries = LiveTemporaries.size();
+
+ EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
+
+ // Pop temporaries.
+ while (LiveTemporaries.size() > OldNumLiveTemporaries)
+ PopCXXTemporary();
+
EmitBlock(ContinueBlock);
// Emit the increment of the loop counter.
@@ -714,7 +735,8 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
BasePtr = llvm::PointerType::getUnqual(BasePtr);
llvm::Value *BaseAddrPtr =
Builder.CreateBitCast(Dest, BasePtr);
- EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr);
+ EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr,
+ E->arg_begin(), E->arg_end());
}
else
// Call the constructor.
@@ -1559,7 +1581,9 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
llvm::Value *BaseAddrPtr =
CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr);
CGF.EmitCXXAggrConstructorCall(MemberInit->getConstructor(),
- Array, BaseAddrPtr);
+ Array, BaseAddrPtr,
+ MemberInit->const_arg_begin(),
+ MemberInit->const_arg_end());
}
else
CGF.EmitCXXConstructorCall(MemberInit->getConstructor(),