Add an assertion in SmallVector::push_back()
authorMehdi Amini <joker.eph@gmail.com>
Fri, 13 Nov 2020 22:37:25 +0000 (22:37 +0000)
committerMehdi Amini <joker.eph@gmail.com>
Sat, 14 Nov 2020 00:55:34 +0000 (00:55 +0000)
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

llvm/include/llvm/ADT/SmallVector.h
llvm/include/llvm/MC/MCInst.h

index e042497..fbc8ede 100644 (file)
@@ -136,6 +136,13 @@ protected:
     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;
@@ -251,6 +258,7 @@ protected:
 
 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);
@@ -258,6 +266,7 @@ public:
   }
 
   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));
@@ -353,6 +362,7 @@ protected:
 
 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));
index 360dbda..2ce2ee0 100644 (file)
@@ -181,7 +181,7 @@ public:
   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;