Skip to content

Commit

Permalink
Add an assertion in SmallVector::push_back()
Browse files Browse the repository at this point in the history
This assertion ensures the input value isn't part of the vector when
growing is required. In such cases the vector will grow and the input
value is invalidated before being read from.

This found 14 failed Tests.

Reviewed By: bkramer

Differential Revision: https://reviews.llvm.org/D84293
  • Loading branch information
joker-eph committed Nov 14, 2020
1 parent 42e88bd commit 2c196bb
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
10 changes: 10 additions & 0 deletions llvm/include/llvm/ADT/SmallVector.h
Expand Up @@ -136,6 +136,13 @@ class SmallVectorTemplateCommon
this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
}

void assertSafeToPush(const void *Elt) {
assert(
(Elt < begin() || Elt >= end() || this->size() < this->capacity()) &&
"Attempting to push_back to the vector an element of the vector without"
" enough space reserved");
}

public:
using size_type = size_t;
using difference_type = ptrdiff_t;
Expand Down Expand Up @@ -251,13 +258,15 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {

public:
void push_back(const T &Elt) {
this->assertSafeToPush(&Elt);
if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void*) this->end()) T(Elt);
this->set_size(this->size() + 1);
}

void push_back(T &&Elt) {
this->assertSafeToPush(&Elt);
if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void*) this->end()) T(::std::move(Elt));
Expand Down Expand Up @@ -353,6 +362,7 @@ class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {

public:
void push_back(const T &Elt) {
this->assertSafeToPush(&Elt);
if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
memcpy(reinterpret_cast<void *>(this->end()), &Elt, sizeof(T));
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/MC/MCInst.h
Expand Up @@ -181,7 +181,7 @@ class MCInst {
MCOperand &getOperand(unsigned i) { return Operands[i]; }
unsigned getNumOperands() const { return Operands.size(); }

void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
void addOperand(const MCOperand Op) { Operands.push_back(Op); }

using iterator = SmallVectorImpl<MCOperand>::iterator;
using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
Expand Down

0 comments on commit 2c196bb

Please sign in to comment.