aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-11 08:38:19 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-11 08:38:19 +0000
commit2673c68aa58e277ebc755b71d81aca618cdedbf9 (patch)
treebac33d78d7e725e30c528d0ac7503b7b6bf0cdaf /lib/CodeGen/CGExprAgg.cpp
parent00d40eae546219786a74564fc0d95eab1978b82b (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.cpp27
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");