Bug 808679 - Add asserts for Vector::Range and Vector srcbeg <= srcend. r=Waldo
authorChris Peterson <cpeterson@mozilla.com>
Tue, 11 Feb 2014 22:42:39 -0800
changeset 171482 61834b158c735d050c6dd1f925ff5a70d0974d5f
parent 171481 543382e6f36778c888515df397fc0566e7072f47
child 171483 56f74fcba1d667d98bcdb4d1e6cdf472bcee8d98
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersWaldo
bugs808679
milestone30.0a1
Bug 808679 - Add asserts for Vector::Range and Vector srcbeg <= srcend. r=Waldo
mfbt/Vector.h
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -54,42 +54,46 @@ static bool CapacityHasExcessSpace(size_
  * This template class provides a default implementation for vector operations
  * when the element type is not known to be a POD, as judged by IsPod.
  */
 template<typename T, size_t N, class AP, class ThisVector, bool IsPod>
 struct VectorImpl
 {
     /* Destroys constructed objects in the range [begin, end). */
     static inline void destroy(T* begin, T* end) {
+      MOZ_ASSERT(begin <= end);
       for (T* p = begin; p < end; ++p)
         p->~T();
     }
 
     /* Constructs objects in the uninitialized range [begin, end). */
     static inline void initialize(T* begin, T* end) {
+      MOZ_ASSERT(begin <= end);
       for (T* p = begin; p < end; ++p)
         new(p) T();
     }
 
     /*
      * Copy-constructs objects in the uninitialized range
      * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend).
      */
     template<typename U>
     static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) {
+      MOZ_ASSERT(srcbeg <= srcend);
       for (const U* p = srcbeg; p < srcend; ++p, ++dst)
         new(dst) T(*p);
     }
 
     /*
      * Move-constructs objects in the uninitialized range
      * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend).
      */
     template<typename U>
     static inline void moveConstruct(T* dst, U* srcbeg, U* srcend) {
+      MOZ_ASSERT(srcbeg <= srcend);
       for (U* p = srcbeg; p < srcend; ++p, ++dst)
         new(dst) T(Move(*p));
     }
 
     /*
      * Copy-constructs objects in the uninitialized range [dst, dst+n) from the
      * same object u.
      */
@@ -139,29 +143,31 @@ struct VectorImpl<T, N, AP, ThisVector, 
       /*
        * You would think that memset would be a big win (or even break even)
        * when we know T is a POD. But currently it's not. This is probably
        * because |append| tends to be given small ranges and memset requires
        * a function call that doesn't get inlined.
        *
        * memset(begin, 0, sizeof(T) * (end-begin));
        */
+      MOZ_ASSERT(begin <= end);
       for (T* p = begin; p < end; ++p)
         new(p) T();
     }
 
     template<typename U>
     static inline void copyConstruct(T* dst, const U* srcbeg, const U* srcend) {
       /*
        * See above memset comment. Also, notice that copyConstruct is
        * currently templated (T != U), so memcpy won't work without
        * requiring T == U.
        *
        * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg));
        */
+      MOZ_ASSERT(srcbeg <= srcend);
       for (const U* p = srcbeg; p < srcend; ++p, ++dst)
         *dst = *p;
     }
 
     template<typename U>
     static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) {
       copyConstruct(dst, srcbeg, srcend);
     }
@@ -386,23 +392,25 @@ class VectorBase : private AllocPolicy
       return *(end() - 1);
     }
 
     class Range
     {
         friend class VectorBase;
         T* cur_;
         T* end_;
-        Range(T* cur, T* end) : cur_(cur), end_(end) {}
+        Range(T* cur, T* end) : cur_(cur), end_(end) {
+          MOZ_ASSERT(cur <= end);
+        }
 
       public:
         Range() {}
         bool empty() const { return cur_ == end_; }
-        size_t remain() const { return end_ - cur_; }
-        T& front() const { return *cur_; }
+        size_t remain() const { return PointerRangeSize(cur_, end_); }
+        T& front() const { MOZ_ASSERT(!empty()); return *cur_; }
         void popFront() { MOZ_ASSERT(!empty()); ++cur_; }
         T popCopyFront() { MOZ_ASSERT(!empty()); return *cur_++; }
     };
 
     Range all() {
       return Range(begin(), end());
     }