forked from OSchip/llvm-project
[SmallPtrSet] Add iterator epoch tracking.
This will detect invalid iterators when ABI breaking checks are enabled. llvm-svn: 315746
This commit is contained in:
parent
f0242de143
commit
d76ed069eb
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_ADT_SMALLPTRSET_H
|
||||
#define LLVM_ADT_SMALLPTRSET_H
|
||||
|
||||
#include "llvm/ADT/EpochTracker.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ReverseIteration.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
@ -46,7 +47,7 @@ namespace llvm {
|
|||
/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
|
||||
/// more. When this happens, the table is doubled in size.
|
||||
///
|
||||
class SmallPtrSetImplBase {
|
||||
class SmallPtrSetImplBase : public DebugEpochBase {
|
||||
friend class SmallPtrSetIteratorImpl;
|
||||
|
||||
protected:
|
||||
|
@ -92,6 +93,7 @@ public:
|
|||
size_type size() const { return NumNonEmpty - NumTombstones; }
|
||||
|
||||
void clear() {
|
||||
incrementEpoch();
|
||||
// If the capacity of the array is huge, and the # elements used is small,
|
||||
// shrink the array.
|
||||
if (!isSmall()) {
|
||||
|
@ -138,12 +140,14 @@ protected:
|
|||
if (LastTombstone != nullptr) {
|
||||
*LastTombstone = Ptr;
|
||||
--NumTombstones;
|
||||
incrementEpoch();
|
||||
return std::make_pair(LastTombstone, true);
|
||||
}
|
||||
|
||||
// Nope, there isn't. If we stay small, just 'pushback' now.
|
||||
if (NumNonEmpty < CurArraySize) {
|
||||
SmallArray[NumNonEmpty++] = Ptr;
|
||||
incrementEpoch();
|
||||
return std::make_pair(SmallArray + (NumNonEmpty - 1), true);
|
||||
}
|
||||
// Otherwise, hit the big set case, which will call grow.
|
||||
|
@ -259,8 +263,9 @@ protected:
|
|||
};
|
||||
|
||||
/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
|
||||
template<typename PtrTy>
|
||||
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
|
||||
template <typename PtrTy>
|
||||
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl,
|
||||
DebugEpochBase::HandleBase {
|
||||
using PtrTraits = PointerLikeTypeTraits<PtrTy>;
|
||||
|
||||
public:
|
||||
|
@ -270,12 +275,14 @@ public:
|
|||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
|
||||
: SmallPtrSetIteratorImpl(BP, E) {}
|
||||
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E,
|
||||
const DebugEpochBase &Epoch)
|
||||
: SmallPtrSetIteratorImpl(BP, E), DebugEpochBase::HandleBase(&Epoch) {}
|
||||
|
||||
// Most methods provided by baseclass.
|
||||
|
||||
const PtrTy operator*() const {
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
if (shouldReverseIterate()) {
|
||||
assert(Bucket > End);
|
||||
return PtrTraits::getFromVoidPointer(const_cast<void *>(Bucket[-1]));
|
||||
|
@ -285,6 +292,7 @@ public:
|
|||
}
|
||||
|
||||
inline SmallPtrSetIterator& operator++() { // Preincrement
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
if (shouldReverseIterate()) {
|
||||
--Bucket;
|
||||
RetreatIfNotValid();
|
||||
|
@ -397,8 +405,8 @@ private:
|
|||
/// Create an iterator that dereferences to same place as the given pointer.
|
||||
iterator makeIterator(const void *const *P) const {
|
||||
if (shouldReverseIterate())
|
||||
return iterator(P == EndPointer() ? CurArray : P + 1, CurArray);
|
||||
return iterator(P, EndPointer());
|
||||
return iterator(P == EndPointer() ? CurArray : P + 1, CurArray, *this);
|
||||
return iterator(P, EndPointer(), *this);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) {
|
|||
else
|
||||
++NumNonEmpty; // Track density.
|
||||
*Bucket = Ptr;
|
||||
incrementEpoch();
|
||||
return std::make_pair(Bucket, true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue