SIL: Avoid dereferencing sentinel nodes in ilist_iterators

The behaviour of ilist has changed in LLVM.  It is no longer permissible to
dereference the `end()` value.  Add a check to ensure that we do not
accidentally dereference the iterator.
This commit is contained in:
Francis Ricci
2016-10-05 17:10:41 -07:00
committed by Saleem Abdulrasool
parent 7d1da2af3d
commit 66dcad0d34
8 changed files with 45 additions and 37 deletions

View File

@@ -180,6 +180,14 @@ inline void set_union_for_each(const Container1 &C1, const Container2 &C2,
set_union_for_each(C1.begin(), C1.end(), C2.begin(), C2.end(), f);
}
/// Takes an iterator and an iterator pointing to the end of the iterator range.
/// If the iterator already points to the end of its range, simply return it,
/// otherwise return the the next element.
template <typename Iterator>
inline Iterator next_or_end(Iterator it, Iterator end) {
return (it == end) ? end : std::next(it);
}
/// @}
/// A range of iterators.

View File

@@ -130,8 +130,7 @@ SILGenFunction::emitEpilogBB(SILLocation TopLevel) {
B.setInsertionPoint(pred);
} else {
// Move the epilog block to the end of the ordinary section.
auto endOfOrdinarySection =
(StartOfPostmatter ? SILFunction::iterator(StartOfPostmatter) : F.end());
auto endOfOrdinarySection = StartOfPostmatter;
B.moveBlockTo(epilogBB, endOfOrdinarySection);
// Emit the epilog into the epilog bb. Its arguments are the

View File

@@ -34,12 +34,9 @@ using namespace Lowering;
//===----------------------------------------------------------------------===//
SILGenFunction::SILGenFunction(SILGenModule &SGM, SILFunction &F)
: SGM(SGM), F(F),
B(*this, createBasicBlock()),
OpenedArchetypesTracker(F),
CurrentSILLoc(F.getLocation()),
Cleanups(*this)
{
: SGM(SGM), F(F), StartOfPostmatter(F.end()), B(*this, createBasicBlock()),
OpenedArchetypesTracker(F), CurrentSILLoc(F.getLocation()),
Cleanups(*this) {
B.setCurrentDebugScope(F.getDebugScope());
B.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
}
@@ -875,8 +872,8 @@ SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
SmallVectorImpl<SILInstruction *> *insertedInsts)
: SILBuilder(insertBB, insertedInsts), SGM(gen.SGM) {}
SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
SILInstruction *insertInst)
: SILBuilder(insertBB, insertInst->getIterator()), SGM(gen.SGM) {}
SILBasicBlock::iterator insertInst)
: SILBuilder(insertBB, insertInst), SGM(gen.SGM) {}
MetatypeInst *SILGenBuilder::createMetatype(SILLocation loc, SILType metatype) {
auto theMetatype = metatype.castTo<MetatypeType>();

View File

@@ -184,7 +184,7 @@ public:
SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
SmallVectorImpl<SILInstruction *> *insertedInsts);
SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
SILInstruction *insertInst);
SILBasicBlock::iterator insertInst);
SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB)
: SILGenBuilder(gen, &*insertBB) {}
@@ -193,10 +193,10 @@ public:
: SILGenBuilder(gen, &*insertBB, insertedInsts) {}
SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
SILInstruction *insertInst)
: SILGenBuilder(gen, &*insertBB, insertInst) {}
: SILGenBuilder(gen, &*insertBB, insertInst->getIterator()) {}
SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
SILBasicBlock::iterator insertInst)
: SILGenBuilder(gen, &*insertBB, &*insertInst) {}
: SILGenBuilder(gen, &*insertBB, insertInst) {}
// Metatype instructions use the conformances necessary to instantiate the
// type.
@@ -319,7 +319,7 @@ public:
///
/// (This field must precede B because B's initializer calls
/// createBasicBlock().)
SILBasicBlock *StartOfPostmatter = nullptr;
SILFunction::iterator StartOfPostmatter;
/// The current section of the function that we're emitting code in.
///
@@ -328,12 +328,12 @@ public:
/// normal code sequence.
///
/// If the current function section is Ordinary, and
/// StartOfPostmatter is non-null, the current insertion block
/// should be ordered before that.
///
/// StartOfPostmatter does not point to the function end, the current
/// insertion block should be ordered before that.
///
/// If the current function section is Postmatter, StartOfPostmatter
/// is non-null and the current insertion block is ordered after
/// that (inclusive).
/// does not point to the function end and the current insertion block is
/// ordered after that (inclusive).
///
/// (This field must precede B because B's initializer calls
/// createBasicBlock().)
@@ -1624,7 +1624,8 @@ public:
: SGF(SGF), SavedIP(SGF.B.getInsertionBB()),
SavedSection(SGF.CurFunctionSection) {
FunctionSection section = (optSection ? *optSection : SavedSection);
assert((section != FunctionSection::Postmatter || SGF.StartOfPostmatter) &&
assert((section != FunctionSection::Postmatter ||
SGF.StartOfPostmatter != SGF.F.end()) &&
"trying to move to postmatter without a registered start "
"of postmatter?");

View File

@@ -110,7 +110,7 @@ SILGenFunction::emitGlobalVariableRef(SILLocation loc, VarDecl *var) {
// Global variables can be accessed directly with global_addr. Emit this
// instruction into the prolog of the function so we can memoize/CSE it in
// VarLocs.
auto entryBB = getFunction().getBlocks().begin();
auto entryBB = getFunction().begin();
SILGenBuilder prologueB(*this, entryBB, entryBB->begin());
prologueB.setTrackingList(B.getTrackingList());

View File

@@ -52,9 +52,9 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) {
case FunctionSection::Ordinary: {
// The end of the ordinary section is just the end of the function
// unless postmatter blocks exist.
SILBasicBlock *afterBB =
(StartOfPostmatter ? &*std::prev(StartOfPostmatter->getIterator())
: nullptr);
SILBasicBlock *afterBB = (StartOfPostmatter != F.end())
? &*std::prev(StartOfPostmatter)
: nullptr;
return new (F.getModule()) SILBasicBlock(&F, afterBB);
}
@@ -62,7 +62,8 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) {
// The end of the postmatter section is always the end of the function.
// Register the new block as the start of the postmatter if needed.
SILBasicBlock *newBB = new (F.getModule()) SILBasicBlock(&F, nullptr);
if (!StartOfPostmatter) StartOfPostmatter = newBB;
if (StartOfPostmatter == F.end())
StartOfPostmatter = newBB->getIterator();
return newBB;
}
@@ -73,8 +74,9 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) {
void SILGenFunction::eraseBasicBlock(SILBasicBlock *block) {
assert(block->pred_empty() && "erasing block with predecessors");
assert(block->empty() && "erasing block with content");
if (block == StartOfPostmatter) {
StartOfPostmatter = &*std::next(block->getIterator());
SILFunction::iterator blockIt = block->getIterator();
if (blockIt == StartOfPostmatter) {
StartOfPostmatter = next_or_end(blockIt, F.end());
}
block->eraseFromParent();
}

View File

@@ -133,15 +133,16 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI,
// See if Continue has a release on self as the instruction right after the
// apply. If it exists, move it into position in the diamond.
if (auto *Release =
dyn_cast<StrongReleaseInst>(std::next(Continue->begin()))) {
if (Release->getOperand() == CMI->getOperand()) {
VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand(),
Atomicity::Atomic);
IdenBuilder.createStrongRelease(
Release->getLoc(), DownCastedClassInstance, Atomicity::Atomic);
Release->eraseFromParent();
}
SILBasicBlock::iterator next =
next_or_end(Continue->begin(), Continue->end());
auto *Release =
(next == Continue->end()) ? nullptr : dyn_cast<StrongReleaseInst>(next);
if (Release && Release->getOperand() == CMI->getOperand()) {
VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand(),
Atomicity::Atomic);
IdenBuilder.createStrongRelease(Release->getLoc(), DownCastedClassInstance,
Atomicity::Atomic);
Release->eraseFromParent();
}
// Create a PHInode for returning the return value from both apply

View File

@@ -319,7 +319,7 @@ template <> struct GraphTraits<StackPromoter *>
return nodes_iterator(SP->getFunction()->end(), SP->getFunction()->end());
}
static unsigned size(GraphType SP) {
return std::distance(nodes_begin(SP), nodes_end(SP));
return std::distance(SP->getFunction()->begin(), SP->getFunction()->end());
}
};