diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-14 00:03:17 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-14 00:03:17 +0000 |
commit | 30e304e2a646ccd5f34d5697cad0be9dcccfaa2d (patch) | |
tree | 163bb6f813594df2306fc76c0ec4241e296b8fb9 /clang/lib/CodeGen/CGExprAgg.cpp | |
parent | 54eb192b25aa766142e19203361f2d91f21b7263 (diff) | |
download | bcm5719-llvm-30e304e2a646ccd5f34d5697cad0be9dcccfaa2d.tar.gz bcm5719-llvm-30e304e2a646ccd5f34d5697cad0be9dcccfaa2d.zip |
Remove custom handling of array copies in lambda by-value array capture and
copy constructors of classes with array members, instead using
ArrayInitLoopExpr to represent the initialization loop.
This exposed a bug in the static analyzer where it was unable to differentiate
between zero-initialized and unknown array values, which has also been fixed
here.
llvm-svn: 289618
Diffstat (limited to 'clang/lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index d756eca64f1..9ead6b86b0c 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -1328,27 +1328,12 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getPointer(), indices, "arrayinit.begin"); - QualType elementType = E->getSubExpr()->getType(); + QualType elementType = + CGF.getContext().getAsArrayType(E->getType())->getElementType(); CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType); CharUnits elementAlign = destPtr.getAlignment().alignmentOfArrayElement(elementSize); - // Prepare for a cleanup. - QualType::DestructionKind dtorKind = elementType.isDestructedType(); - Address endOfInit = Address::invalid(); - EHScopeStack::stable_iterator cleanup; - llvm::Instruction *cleanupDominator = nullptr; - if (CGF.needsEHCleanup(dtorKind)) { - endOfInit = CGF.CreateTempAlloca(begin->getType(), CGF.getPointerAlign(), - "arrayinit.endOfInit"); - CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, - elementAlign, - CGF.getDestroyer(dtorKind)); - cleanup = CGF.EHStack.stable_begin(); - } else { - dtorKind = QualType::DK_none; - } - llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); @@ -1359,11 +1344,22 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { index->addIncoming(zero, entryBB); llvm::Value *element = Builder.CreateInBoundsGEP(begin, index); - // Tell the EH cleanup that we finished with the last element. - if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit); + // Prepare for a cleanup. + QualType::DestructionKind dtorKind = elementType.isDestructedType(); + EHScopeStack::stable_iterator cleanup; + if (CGF.needsEHCleanup(dtorKind)) { + CGF.pushRegularPartialArrayCleanup( + begin, element, elementType, elementAlign, CGF.getDestroyer(dtorKind)); + cleanup = CGF.EHStack.stable_begin(); + } else { + dtorKind = QualType::DK_none; + } // Emit the actual filler expression. { + // Temporaries created in an array initialization loop are destroyed + // at the end of each iteration. + CodeGenFunction::RunCleanupsScope CleanupsScope(CGF); CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index); LValue elementLV = CGF.MakeAddrLValue(Address(element, elementAlign), elementType); @@ -1385,7 +1381,8 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { CGF.EmitBlock(endBB); // Leave the partial-array cleanup if we entered one. - if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator); + if (dtorKind) + CGF.DeactivateCleanupBlock(cleanup, index); } void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) { |