Add Address Sanitizer support to std::vector
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@208319 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -483,6 +483,7 @@ class _LIBCPP_TYPE_VIS_ONLY vector
|
||||
{
|
||||
private:
|
||||
typedef __vector_base<_Tp, _Allocator> __base;
|
||||
typedef allocator<_Tp> __default_allocator_type;
|
||||
public:
|
||||
typedef vector __self;
|
||||
typedef _Tp value_type;
|
||||
@@ -749,7 +750,9 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void clear() _NOEXCEPT
|
||||
{
|
||||
size_type __old_size = size();
|
||||
__base::clear();
|
||||
__annotate_shrink(__old_size);
|
||||
__invalidate_all_iterators();
|
||||
}
|
||||
|
||||
@@ -816,7 +819,9 @@ private:
|
||||
}
|
||||
__get_db()->unlock();
|
||||
#endif
|
||||
size_type __old_size = size();
|
||||
__base::__destruct_at_end(__new_last);
|
||||
__annotate_shrink(__old_size);
|
||||
}
|
||||
template <class _Up>
|
||||
void
|
||||
@@ -830,17 +835,52 @@ private:
|
||||
void
|
||||
__emplace_back_slow_path(_Args&&... __args);
|
||||
#endif
|
||||
// The following functions are no-ops outside of AddressSanitizer mode.
|
||||
// We call annotatations only for the default Allocator because other allocators
|
||||
// may not meet the AddressSanitizer alignment constraints.
|
||||
// See the documentation for __sanitizer_annotate_contiguous_container for more details.
|
||||
void __annotate_contiguous_container
|
||||
(const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid)
|
||||
{
|
||||
#ifndef _LIBCPP_HAS_NO_ASAN
|
||||
if (__beg && is_same<allocator_type, __default_allocator_type>::value)
|
||||
__sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __annotate_new(size_type __current_size)
|
||||
{
|
||||
__annotate_contiguous_container(data(), data() + capacity(),
|
||||
data() + capacity(), data() + __current_size);
|
||||
}
|
||||
void __annotate_delete()
|
||||
{
|
||||
__annotate_contiguous_container(data(), data() + capacity(),
|
||||
data() + size(), data() + capacity());
|
||||
}
|
||||
void __annotate_increase(size_type __n)
|
||||
{
|
||||
__annotate_contiguous_container(data(), data() + capacity(),
|
||||
data() + size(), data() + size() + __n);
|
||||
}
|
||||
void __annotate_shrink(size_type __old_size)
|
||||
{
|
||||
__annotate_contiguous_container(data(), data() + capacity(),
|
||||
data() + __old_size, data() + size());
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
void
|
||||
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
|
||||
{
|
||||
__annotate_delete();
|
||||
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
|
||||
_VSTD::swap(this->__begin_, __v.__begin_);
|
||||
_VSTD::swap(this->__end_, __v.__end_);
|
||||
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
||||
__v.__first_ = __v.__begin_;
|
||||
__annotate_new(size());
|
||||
__invalidate_all_iterators();
|
||||
}
|
||||
|
||||
@@ -848,6 +888,7 @@ template <class _Tp, class _Allocator>
|
||||
typename vector<_Tp, _Allocator>::pointer
|
||||
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)
|
||||
{
|
||||
__annotate_delete();
|
||||
pointer __r = __v.__begin_;
|
||||
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
|
||||
__alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
|
||||
@@ -855,6 +896,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
|
||||
_VSTD::swap(this->__end_, __v.__end_);
|
||||
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
||||
__v.__first_ = __v.__begin_;
|
||||
__annotate_new(size());
|
||||
__invalidate_all_iterators();
|
||||
return __r;
|
||||
}
|
||||
@@ -874,6 +916,7 @@ vector<_Tp, _Allocator>::allocate(size_type __n)
|
||||
this->__throw_length_error();
|
||||
this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);
|
||||
this->__end_cap() = this->__begin_ + __n;
|
||||
__annotate_new(0);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
@@ -920,6 +963,7 @@ void
|
||||
vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
|
||||
{
|
||||
allocator_type& __a = this->__alloc();
|
||||
__annotate_increase(__n);
|
||||
do
|
||||
{
|
||||
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
|
||||
@@ -940,6 +984,7 @@ void
|
||||
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
|
||||
{
|
||||
allocator_type& __a = this->__alloc();
|
||||
__annotate_increase(__n);
|
||||
do
|
||||
{
|
||||
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
|
||||
@@ -960,6 +1005,7 @@ vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIt
|
||||
allocator_type& __a = this->__alloc();
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
__annotate_increase(1);
|
||||
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
|
||||
++this->__end_;
|
||||
}
|
||||
@@ -972,6 +1018,7 @@ vector<_Tp, _Allocator>::__move_construct_at_end(pointer __first, pointer __last
|
||||
allocator_type& __a = this->__alloc();
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
__annotate_increase(1);
|
||||
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
|
||||
_VSTD::move(*__first));
|
||||
++this->__end_;
|
||||
@@ -1535,6 +1582,7 @@ vector<_Tp, _Allocator>::push_back(const_reference __x)
|
||||
{
|
||||
if (this->__end_ != this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
_VSTD::__to_raw_pointer(this->__end_), __x);
|
||||
++this->__end_;
|
||||
@@ -1552,6 +1600,7 @@ vector<_Tp, _Allocator>::push_back(value_type&& __x)
|
||||
{
|
||||
if (this->__end_ < this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
_VSTD::__to_raw_pointer(this->__end_),
|
||||
_VSTD::move(__x));
|
||||
@@ -1584,6 +1633,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
|
||||
{
|
||||
if (this->__end_ < this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
_VSTD::__to_raw_pointer(this->__end_),
|
||||
_VSTD::forward<_Args>(__args)...);
|
||||
@@ -1666,6 +1716,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
|
||||
pointer __p = this->__begin_ + (__position - begin());
|
||||
if (this->__end_ < this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
if (__p == this->__end_)
|
||||
{
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
@@ -1705,6 +1756,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
|
||||
pointer __p = this->__begin_ + (__position - begin());
|
||||
if (this->__end_ < this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
if (__p == this->__end_)
|
||||
{
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
@@ -1743,6 +1795,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
|
||||
pointer __p = this->__begin_ + (__position - begin());
|
||||
if (this->__end_ < this->__end_cap())
|
||||
{
|
||||
__annotate_increase(1);
|
||||
if (__p == this->__end_)
|
||||
{
|
||||
__alloc_traits::construct(this->__alloc(),
|
||||
@@ -1794,6 +1847,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_
|
||||
}
|
||||
if (__n > 0)
|
||||
{
|
||||
__annotate_increase(__n);
|
||||
__move_range(__p, __old_last, __p + __old_n);
|
||||
const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
|
||||
if (__p <= __xr && __xr < this->__end_)
|
||||
@@ -1904,6 +1958,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi
|
||||
}
|
||||
if (__n > 0)
|
||||
{
|
||||
__annotate_increase(__n);
|
||||
__move_range(__p, __old_last, __p + __old_n);
|
||||
_VSTD::copy(__first, __m, __p);
|
||||
}
|
||||
|
Reference in New Issue
Block a user