diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-16 11:35:52 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-16 11:35:52 +0000 |
commit | 1548d14f4092a817f7d90ad3e7a65266dc85fbc5 (patch) | |
tree | 9598a6e0e3d1961c32a7ab570360ada0a543eb6c /lib/CodeGen/CGExprCXX.cpp | |
parent | 5f688f4b15d02aa7ad159c46b1f78fe59d412f12 (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.cpp | 51 |
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); |