diff options
author | John McCall <rjmccall@apple.com> | 2011-07-11 08:38:19 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-11 08:38:19 +0000 |
commit | 2673c68aa58e277ebc755b71d81aca618cdedbf9 (patch) | |
tree | bac33d78d7e725e30c528d0ac7503b7b6bf0cdaf /lib/CodeGen/CGExprAgg.cpp | |
parent | 00d40eae546219786a74564fc0d95eab1978b82b (diff) |
Fix a lot of problems with the partial destruction of arrays:
- an off-by-one error in emission of irregular array limits for
InitListExprs
- use an EH partial-destruction cleanup within the normal
array-destruction cleanup
- get the branch destinations right for the empty check
Also some refactoring which unfortunately obscures these changes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 1d473f6012..062e13d2b6 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -689,8 +689,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { endOfInit = CGF.CreateTempAlloca(begin->getType(), "arrayinit.endOfInit"); Builder.CreateStore(begin, endOfInit); - CGF.pushPartialArrayCleanup(begin, elementType, - CGF.getDestroyer(dtorKind), endOfInit); + CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, + CGF.getDestroyer(dtorKind)); cleanup = CGF.EHStack.stable_begin(); // Otherwise, remember that we didn't need a cleanup. @@ -710,16 +710,17 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // Emit the explicit initializers. for (uint64_t i = 0; i != NumInitElements; ++i) { // Advance to the next element. - if (i > 0) + if (i > 0) { element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element"); + // Tell the cleanup that it needs to destroy up to this + // element. TODO: some of these stores can be trivially + // observed to be unnecessary. + if (endOfInit) Builder.CreateStore(element, endOfInit); + } + LValue elementLV = CGF.MakeAddrLValue(element, elementType); EmitInitializationToLValue(E->getInit(i), elementLV); - - // Tell the cleanup that it needs to destroy this element. - // TODO: some of these stores can be trivially observed to be - // unnecessary. - if (endOfInit) Builder.CreateStore(element, endOfInit); } // Check whether there's a non-trivial array-fill expression. @@ -743,8 +744,10 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // do { *array++ = filler; } while (array != end); // Advance to the start of the rest of the array. - if (NumInitElements) + if (NumInitElements) { element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start"); + if (endOfInit) Builder.CreateStore(element, endOfInit); + } // Compute the end of the array. llvm::Value *end = Builder.CreateInBoundsGEP(begin, @@ -767,13 +770,13 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { else EmitNullInitializationToLValue(elementLV); - // Tell the EH cleanup that we finished with that element. - if (endOfInit) Builder.CreateStore(element, endOfInit); - // Move on to the next element. llvm::Value *nextElement = Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next"); + // Tell the EH cleanup that we finished with the last element. + if (endOfInit) Builder.CreateStore(nextElement, endOfInit); + // Leave the loop if we're done. llvm::Value *done = Builder.CreateICmpEQ(nextElement, end, "arrayinit.done"); |