aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-16 11:35:52 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-16 11:35:52 +0000
commit1548d14f4092a817f7d90ad3e7a65266dc85fbc5 (patch)
tree9598a6e0e3d1961c32a7ab570360ada0a543eb6c /lib/CodeGen/CGExprCXX.cpp
parent5f688f4b15d02aa7ad159c46b1f78fe59d412f12 (diff)
Revert "Make CXXNewExpr contain only a single initialier, and not hold the used constructor itself."
It leads to a compiler crash in the Bullet benchmark. This reverts commit r12014. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150684 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--lib/CodeGen/CGExprCXX.cpp51
1 files changed, 29 insertions, 22 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 12bdc7e43f..7b1ae1cc24 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -743,8 +743,11 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
llvm::Value *NewPtr) {
-
- const Expr *Init = E->getInitializer();
+
+ assert(E->getNumConstructorArgs() == 1 &&
+ "Can only have one argument to initializer of POD type.");
+
+ const Expr *Init = E->getConstructorArg(0);
QualType AllocType = E->getAllocatedType();
CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
@@ -770,8 +773,9 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E,
QualType elementType,
llvm::Value *beginPtr,
llvm::Value *numElements) {
- if (!E->hasInitializer())
- return; // We have a POD type.
+ // We have a POD type.
+ if (E->getNumConstructorArgs() == 0)
+ return;
// Check if the number of elements is constant.
bool checkZero = true;
@@ -854,15 +858,13 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
llvm::Value *NewPtr,
llvm::Value *NumElements,
llvm::Value *AllocSizeWithoutCookie) {
- const Expr *Init = E->getInitializer();
if (E->isArray()) {
- if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
- CXXConstructorDecl *Ctor = CCE->getConstructor();
+ if (CXXConstructorDecl *Ctor = E->getConstructor()) {
bool RequiresZeroInitialization = false;
if (Ctor->getParent()->hasTrivialDefaultConstructor()) {
// If new expression did not specify value-initialization, then there
// is no initialization.
- if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
+ if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
return;
if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
@@ -875,38 +877,43 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
RequiresZeroInitialization = true;
}
- CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
- CCE->arg_begin(), CCE->arg_end(),
+ CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
+ E->constructor_arg_begin(),
+ E->constructor_arg_end(),
RequiresZeroInitialization);
return;
- } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
+ } else if (E->getNumConstructorArgs() == 1 &&
+ isa<ImplicitValueInitExpr>(E->getConstructorArg(0)) &&
CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
// Optimization: since zero initialization will just set the memory
// to all zeroes, generate a single memset to do it in one shot.
EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
return;
+ } else {
+ CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
+ return;
}
- CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
- return;
}
- if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)) {
- CXXConstructorDecl *Ctor = CCE->getConstructor();
+ if (CXXConstructorDecl *Ctor = E->getConstructor()) {
// Per C++ [expr.new]p15, if we have an initializer, then we're performing
// direct initialization. C++ [dcl.init]p5 requires that we
// zero-initialize storage if there are no user-declared constructors.
- if (!Ctor->getParent()->hasUserDeclaredConstructor() &&
+ if (E->hasInitializer() &&
+ !Ctor->getParent()->hasUserDeclaredConstructor() &&
!Ctor->getParent()->isEmpty())
CGF.EmitNullInitialization(NewPtr, ElementType);
+
+ CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
+ NewPtr, E->constructor_arg_begin(),
+ E->constructor_arg_end());
- CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
- NewPtr, CCE->arg_begin(), CCE->arg_end());
return;
}
// We have a POD type.
- if (!Init)
+ if (E->getNumConstructorArgs() == 0)
return;
-
+
StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
}
@@ -1138,7 +1145,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
// CXXNewExpr::shouldNullCheckAllocation()) and we have an
// interesting initializer.
bool nullCheck = allocatorType->isNothrow(getContext()) &&
- (!allocType.isPODType(getContext()) || E->hasInitializer());
+ !(allocType.isPODType(getContext()) && !E->hasInitializer());
llvm::BasicBlock *nullCheckBB = 0;
llvm::BasicBlock *contBB = 0;
@@ -1204,7 +1211,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
cleanupDominator->eraseFromParent();
}
-
+
if (nullCheck) {
conditional.end(*this);