Initial checkin for debug mode (version 2)
llvm-svn: 139711
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: f554add54e3e9d430dd2646536fe7c475ff090d7
diff --git a/include/vector b/include/vector
index 348fe4a..d1a67ce 100644
--- a/include/vector
+++ b/include/vector
@@ -513,8 +513,18 @@
_LIBCPP_INLINE_VISIBILITY
vector()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
- {}
- _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) : __base(__a) {}
+ {
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
+ }
+ _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
+ : __base(__a)
+ {
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
+ }
explicit vector(size_type __n);
vector(size_type __n, const_reference __x);
vector(size_type __n, const_reference __x, const allocator_type& __a);
@@ -538,9 +548,12 @@
_LIBCPP_INLINE_VISIBILITY
vector(initializer_list<value_type> __il, const allocator_type& __a);
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
_LIBCPP_INLINE_VISIBILITY
- ~vector() {__invalidate_all_iterators();}
+ ~vector()
+ {
+ __get_db()->__erase_c(this);
+ }
#endif
vector(const vector& __x);
@@ -641,10 +654,26 @@
reference at(size_type __n);
const_reference at(size_type __n) const;
- _LIBCPP_INLINE_VISIBILITY reference front() {return *this->__begin_;}
- _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *this->__begin_;}
- _LIBCPP_INLINE_VISIBILITY reference back() {return *(this->__end_ - 1);}
- _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(this->__end_ - 1);}
+ _LIBCPP_INLINE_VISIBILITY reference front()
+ {
+ _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+ return *this->__begin_;
+ }
+ _LIBCPP_INLINE_VISIBILITY const_reference front() const
+ {
+ _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+ return *this->__begin_;
+ }
+ _LIBCPP_INLINE_VISIBILITY reference back()
+ {
+ _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+ return *(this->__end_ - 1);
+ }
+ _LIBCPP_INLINE_VISIBILITY const_reference back() const
+ {
+ _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+ return *(this->__end_ - 1);
+ }
_LIBCPP_INLINE_VISIBILITY
value_type* data() _NOEXCEPT
@@ -698,7 +727,10 @@
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT
- {__base::clear();}
+ {
+ __base::clear();
+ __invalidate_all_iterators();
+ }
void resize(size_type __sz);
void resize(size_type __sz, const_reference __x);
@@ -709,6 +741,15 @@
bool __invariants() const;
+#ifdef _LIBCPP_DEBUG2
+
+ bool __dereferenceable(const const_iterator* __i) const;
+ bool __decrementable(const const_iterator* __i) const;
+ bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+ bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif // _LIBCPP_DEBUG2
+
private:
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
void allocate(size_type __n);
@@ -736,6 +777,26 @@
void __move_assign(vector& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
void __move_assign(vector& __c, false_type);
+ _LIBCPP_INLINE_VISIBILITY
+ void __destruct_at_end(const_pointer __new_last) _NOEXCEPT
+ {
+#ifdef _LIBCPP_DEBUG2
+ __c_node* __c = __get_db()->__find_c_and_lock(this);
+ for (__i_node** __p = __c->end_; __p != __c->beg_; )
+ {
+ --__p;
+ const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+ if (__i->base() > __new_last)
+ {
+ (*__p)->__c_ = nullptr;
+ if (--__c->end_ != __p)
+ memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+ }
+ }
+ __get_db()->unlock();
+#endif
+ __base::__destruct_at_end(__new_last);
+ }
};
template <class _Tp, class _Allocator>
@@ -793,7 +854,6 @@
{
clear();
__alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
- __invalidate_all_iterators();
this->__begin_ = this->__end_ = this->__end_cap() = 0;
}
}
@@ -934,6 +994,9 @@
allocate(__n);
__construct_at_end(__n);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -944,6 +1007,9 @@
allocate(__n);
__construct_at_end(__n, __x);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -955,6 +1021,9 @@
allocate(__n);
__construct_at_end(__n, __x);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -965,6 +1034,9 @@
{
for (; __first != __last; ++__first)
push_back(*__first);
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -976,6 +1048,9 @@
{
for (; __first != __last; ++__first)
push_back(*__first);
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -989,6 +1064,9 @@
allocate(__n);
__construct_at_end(__first, __last);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -1003,6 +1081,9 @@
allocate(__n);
__construct_at_end(__first, __last);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -1015,6 +1096,9 @@
allocate(__n);
__construct_at_end(__x.__begin_, __x.__end_);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -1027,6 +1111,9 @@
allocate(__n);
__construct_at_end(__x.__begin_, __x.__end_);
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1041,7 +1128,10 @@
this->__end_ = __x.__end_;
this->__end_cap() = __x.__end_cap();
__x.__begin_ = __x.__end_ = __x.__end_cap() = 0;
+#ifdef _LIBCPP_DEBUG2
__x.__invalidate_all_iterators();
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -1062,6 +1152,9 @@
typedef move_iterator<iterator> _I;
assign(_I(__x.begin()), _I(__x.end()));
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -1075,6 +1168,9 @@
allocate(__il.size());
__construct_at_end(__il.begin(), __il.end());
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
template <class _Tp, class _Allocator>
@@ -1087,6 +1183,9 @@
allocate(__il.size());
__construct_at_end(__il.begin(), __il.end());
}
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__insert_c(this);
+#endif
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -1220,7 +1319,7 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
{
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
return iterator(this, __p);
#else
return iterator(__p);
@@ -1232,7 +1331,7 @@
typename vector<_Tp, _Allocator>::const_iterator
vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
{
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
return const_iterator(this, __p);
#else
return const_iterator(__p);
@@ -1276,9 +1375,7 @@
typename vector<_Tp, _Allocator>::reference
vector<_Tp, _Allocator>::operator[](size_type __n)
{
-#ifdef _LIBCPP_DEBUG
- assert(__n < size());
-#endif
+ _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
@@ -1287,9 +1384,7 @@
typename vector<_Tp, _Allocator>::const_reference
vector<_Tp, _Allocator>::operator[](size_type __n) const
{
-#ifdef _LIBCPP_DEBUG
- assert(__n < size());
-#endif
+ _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
@@ -1417,6 +1512,7 @@
void
vector<_Tp, _Allocator>::pop_back()
{
+ _LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector");
this->__destruct_at_end(this->__end_ - 1);
}
@@ -1425,6 +1521,9 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __position)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::erase(iterator) called with an iterator not"
+ " referring to this vector");
pointer __p = const_cast<pointer>(&*__position);
iterator __r = __make_iter(__p);
this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
@@ -1435,6 +1534,10 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+ "vector::erase(iterator, iterator) called with an iterator not"
+ " referring to this vector");
+ _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
pointer __p = this->__begin_ + (__first - begin());
iterator __r = __make_iter(__p);
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
@@ -1458,6 +1561,9 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::insert(iterator, x) called with an iterator not"
+ " referring to this vector");
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
@@ -1492,6 +1598,9 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::insert(iterator, x) called with an iterator not"
+ " referring to this vector");
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
@@ -1525,6 +1634,9 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::emplace(iterator, x) called with an iterator not"
+ " referring to this vector");
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
@@ -1558,6 +1670,9 @@
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::insert(iterator, n, x) called with an iterator not"
+ " referring to this vector");
pointer __p = this->__begin_ + (__position - begin());
if (__n > 0)
{
@@ -1601,6 +1716,9 @@
>::type
vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::insert(iterator, range) called with an iterator not"
+ " referring to this vector");
difference_type __off = __position - begin();
pointer __p = this->__begin_ + __off;
allocator_type& __a = this->__alloc();
@@ -1648,6 +1766,9 @@
>::type
vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
{
+ _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+ "vector::insert(iterator, range) called with an iterator not"
+ " referring to this vector");
pointer __p = this->__begin_ + (__position - begin());
difference_type __n = _VSTD::distance(__first, __last);
if (__n > 0)
@@ -1710,13 +1831,16 @@
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
{
+ _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
+ this->__alloc() == __x.__alloc(),
+ "vector::swap: Either propagate_on_container_swap must be true"
+ " or the allocators must compare equal");
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__end_, __x.__end_);
_VSTD::swap(this->__end_cap(), __x.__end_cap());
__base::__swap_alloc(this->__alloc(), __x.__alloc());
-#ifdef _LIBCPP_DEBUG
- iterator::swap(this, &__x);
- const_iterator::swap(this, &__x);
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->swap(this, &__x);
#endif // _LIBCPP_DEBUG
}
@@ -1741,16 +1865,49 @@
return true;
}
+#ifdef _LIBCPP_DEBUG2
+
template <class _Tp, class _Allocator>
-#ifndef _LIBCPP_DEBUG
+bool
+vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+ return this->__begin_ <= __i->base() && __i->base() < this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+ return this->__begin_ < __i->base() && __i->base() <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+ const_pointer __p = __i->base() + __n;
+ return this->__begin_ <= __p && __p <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+ const_pointer __p = __i->base() + __n;
+ return this->__begin_ <= __p && __p < this->__end_;
+}
+
+#endif // LIBCPP_DEBUG2
+
+template <class _Tp, class _Allocator>
_LIBCPP_INLINE_VISIBILITY inline
-#endif
void
vector<_Tp, _Allocator>::__invalidate_all_iterators()
{
-#ifdef _LIBCPP_DEBUG
- iterator::__remove_all(this);
- const_iterator::__remove_all(this);
+#ifdef _LIBCPP_DEBUG2
+ __get_db()->__invalidate_all(this);
+// iterator::__remove_all(this);
+// const_iterator::__remove_all(this);
#endif // _LIBCPP_DEBUG
}