From 8c7331c5563e00e63837d0246f1325371157d46a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 21 Jul 2017 17:05:10 +0100 Subject: [PATCH] Add AddressSanitizer annotations to std::vector * config/allocator/malloc_allocator_base.h [__SANITIZE_ADDRESS__] (_GLIBCXX_SANITIZE_STD_ALLOCATOR): Define. * config/allocator/new_allocator_base.h [__SANITIZE_ADDRESS__] (_GLIBCXX_SANITIZE_STD_ALLOCATOR): Define. * doc/xml/manual/using.xml (_GLIBCXX_SANITIZE_VECTOR): Document macro. * include/bits/stl_vector.h [_GLIBCXX_SANITIZE_VECTOR] (_Vector_impl::_Asan, _Vector_impl::_Asan::_Reinit) (_Vector_impl::_Asan::_Grow, _GLIBCXX_ASAN_ANNOTATE_REINIT) (_GLIBCXX_ASAN_ANNOTATE_GROW, _GLIBCXX_ASAN_ANNOTATE_GREW) (_GLIBCXX_ASAN_ANNOTATE_SHRINK, _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC): Define annotation helper types and macros. (vector::~vector, vector::push_back, vector::pop_back) (vector::_M_erase_at_end): Add annotations. * include/bits/vector.tcc (vector::reserve, vector::emplace_back) (vector::insert, vector::_M_erase, vector::operator=) (vector::_M_fill_assign, vector::_M_assign_aux) (vector::_M_insert_rval, vector::_M_emplace_aux) (vector::_M_insert_aux, vector::_M_realloc_insert) (vector::_M_fill_insert, vector::_M_default_append) (vector::_M_shrink_to_fit, vector::_M_range_insert): Annotate. From-SVN: r250430 --- libstdc++-v3/ChangeLog | 23 ++++ .../config/allocator/malloc_allocator_base.h | 4 + libstdc++-v3/config/allocator/new_allocator_base.h | 4 + libstdc++-v3/doc/xml/manual/using.xml | 18 +++ libstdc++-v3/include/bits/stl_vector.h | 146 ++++++++++++++++++++- libstdc++-v3/include/bits/vector.tcc | 51 ++++++- 6 files changed, 234 insertions(+), 12 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d60c570..6d82766 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2017-07-20 Jonathan Wakely + + * config/allocator/malloc_allocator_base.h [__SANITIZE_ADDRESS__] + (_GLIBCXX_SANITIZE_STD_ALLOCATOR): Define. + * config/allocator/new_allocator_base.h [__SANITIZE_ADDRESS__] + (_GLIBCXX_SANITIZE_STD_ALLOCATOR): Define. + * doc/xml/manual/using.xml (_GLIBCXX_SANITIZE_VECTOR): Document macro. + * include/bits/stl_vector.h [_GLIBCXX_SANITIZE_VECTOR] + (_Vector_impl::_Asan, _Vector_impl::_Asan::_Reinit) + (_Vector_impl::_Asan::_Grow, _GLIBCXX_ASAN_ANNOTATE_REINIT) + (_GLIBCXX_ASAN_ANNOTATE_GROW, _GLIBCXX_ASAN_ANNOTATE_GREW) + (_GLIBCXX_ASAN_ANNOTATE_SHRINK, _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC): + Define annotation helper types and macros. + (vector::~vector, vector::push_back, vector::pop_back) + (vector::_M_erase_at_end): Add annotations. + * include/bits/vector.tcc (vector::reserve, vector::emplace_back) + (vector::insert, vector::_M_erase, vector::operator=) + (vector::_M_fill_assign, vector::_M_assign_aux) + (vector::_M_insert_rval, vector::_M_emplace_aux) + (vector::_M_insert_aux, vector::_M_realloc_insert) + (vector::_M_fill_insert, vector::_M_default_append) + (vector::_M_shrink_to_fit, vector::_M_range_insert): Annotate. + 2017-07-19 Jonathan Wakely PR libstdc++/81476 diff --git a/libstdc++-v3/config/allocator/malloc_allocator_base.h b/libstdc++-v3/config/allocator/malloc_allocator_base.h index b091bbc..54e0837 100644 --- a/libstdc++-v3/config/allocator/malloc_allocator_base.h +++ b/libstdc++-v3/config/allocator/malloc_allocator_base.h @@ -52,4 +52,8 @@ namespace std # define __allocator_base __gnu_cxx::malloc_allocator #endif +#if defined(__SANITIZE_ADDRESS__) && !defined(_GLIBCXX_SANITIZE_STD_ALLOCATOR) +# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1 +#endif + #endif diff --git a/libstdc++-v3/config/allocator/new_allocator_base.h b/libstdc++-v3/config/allocator/new_allocator_base.h index 3d2bb67..e776ed3 100644 --- a/libstdc++-v3/config/allocator/new_allocator_base.h +++ b/libstdc++-v3/config/allocator/new_allocator_base.h @@ -52,4 +52,8 @@ namespace std # define __allocator_base __gnu_cxx::new_allocator #endif +#if defined(__SANITIZE_ADDRESS__) && !defined(_GLIBCXX_SANITIZE_STD_ALLOCATOR) +# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1 +#endif + #endif diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml index 5c0e1b9..6ce29fd 100644 --- a/libstdc++-v3/doc/xml/manual/using.xml +++ b/libstdc++-v3/doc/xml/manual/using.xml @@ -991,6 +991,24 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe + _GLIBCXX_SANITIZE_VECTOR + + + Undefined by default. When defined, std::vector + operations will be annotated so that AddressSanitizer can detect + invalid accesses to the unused capacity of a + std::vector. These annotations are only + enabled for + std::vector<T, std::allocator<T>> + and only when std::allocator is derived from + new_allocator + or malloc_allocator. The annotations + must be present on all vector operations or none, so this macro must + be defined to the same value for all translation units that create, + destroy or modify vectors. + + +
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 7ee3ce9..c7787f7 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -65,6 +65,12 @@ #include +#if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR +extern "C" void +__sanitizer_annotate_contiguous_container(const void*, const void*, + const void*, const void*); +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER @@ -106,6 +112,121 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::swap(_M_finish, __x._M_finish); std::swap(_M_end_of_storage, __x._M_end_of_storage); } + +#if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR + template + struct _Asan + { + typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> + ::size_type size_type; + + static void _S_shrink(_Vector_impl&, size_type) { } + static void _S_on_dealloc(_Vector_impl&) { } + + typedef _Vector_impl& _Reinit; + + struct _Grow + { + _Grow(_Vector_impl&, size_type) { } + void _M_grew(size_type) { } + }; + }; + + // Enable ASan annotations for memory obtained from std::allocator. + template + struct _Asan > + { + typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> + ::size_type size_type; + + // Adjust ASan annotation for [_M_start, _M_end_of_storage) to + // mark end of valid region as __curr instead of __prev. + static void + _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr) + { + __sanitizer_annotate_contiguous_container(__impl._M_start, + __impl._M_end_of_storage, __prev, __curr); + } + + static void + _S_grow(_Vector_impl& __impl, size_type __n) + { _S_adjust(__impl, __impl._M_finish, __impl._M_finish + __n); } + + static void + _S_shrink(_Vector_impl& __impl, size_type __n) + { _S_adjust(__impl, __impl._M_finish + __n, __impl._M_finish); } + + static void + _S_on_dealloc(_Vector_impl& __impl) + { + if (__impl._M_start) + _S_adjust(__impl, __impl._M_finish, __impl._M_end_of_storage); + } + + // Used on reallocation to tell ASan unused capacity is invalid. + struct _Reinit + { + explicit _Reinit(_Vector_impl& __impl) : _M_impl(__impl) + { + // Mark unused capacity as valid again before deallocating it. + _S_on_dealloc(_M_impl); + } + + ~_Reinit() + { + // Mark unused capacity as invalid after reallocation. + if (_M_impl._M_start) + _S_adjust(_M_impl, _M_impl._M_end_of_storage, + _M_impl._M_finish); + } + + _Vector_impl& _M_impl; + +#if __cplusplus >= 201103L + _Reinit(const _Reinit&) = delete; + _Reinit& operator=(const _Reinit&) = delete; +#endif + }; + + // Tell ASan when unused capacity is initialized to be valid. + struct _Grow + { + _Grow(_Vector_impl& __impl, size_type __n) + : _M_impl(__impl), _M_n(__n) + { _S_grow(_M_impl, __n); } + + ~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); } + + void _M_grew(size_type __n) { _M_n -= __n; } + +#if __cplusplus >= 201103L + _Grow(const _Grow&) = delete; + _Grow& operator=(const _Grow&) = delete; +#endif + private: + _Vector_impl& _M_impl; + size_type _M_n; + }; + }; + +#define _GLIBCXX_ASAN_ANNOTATE_REINIT \ + typename _Base::_Vector_impl::template _Asan<>::_Reinit const \ + __attribute__((__unused__)) __reinit_guard(this->_M_impl) +#define _GLIBCXX_ASAN_ANNOTATE_GROW(n) \ + typename _Base::_Vector_impl::template _Asan<>::_Grow \ + __attribute__((__unused__)) __grow_guard(this->_M_impl, (n)) +#define _GLIBCXX_ASAN_ANNOTATE_GREW(n) __grow_guard._M_grew(n) +#define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) \ + _Base::_Vector_impl::template _Asan<>::_S_shrink(this->_M_impl, n) +#define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC \ + _Base::_Vector_impl::template _Asan<>::_S_on_dealloc(this->_M_impl) +#else // ! (_GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR) +#define _GLIBCXX_ASAN_ANNOTATE_REINIT +#define _GLIBCXX_ASAN_ANNOTATE_GROW(n) +#define _GLIBCXX_ASAN_ANNOTATE_GREW(n) +#define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) +#define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC +#endif // _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR }; public: @@ -159,8 +280,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif ~_Vector_base() _GLIBCXX_NOEXCEPT - { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - - this->_M_impl._M_start); } + { + _M_deallocate(_M_impl._M_start, + _M_impl._M_end_of_storage - _M_impl._M_start); + } public: _Vector_impl _M_impl; @@ -431,8 +554,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * responsibility. */ ~vector() _GLIBCXX_NOEXCEPT - { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, - _M_get_Tp_allocator()); } + { + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC; + } /** * @brief %Vector assignment operator. @@ -940,9 +1066,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_realloc_insert(end(), __x); @@ -977,6 +1105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER __glibcxx_requires_nonempty(); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); } #if __cplusplus >= 201103L @@ -1510,8 +1639,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT { - std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); - this->_M_impl._M_finish = __pos; + if (size_type __n = this->_M_impl._M_finish - __pos) + { + std::_Destroy(__pos, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = __pos; + _GLIBCXX_ASAN_ANNOTATE_SHRINK(__n); + } } iterator diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index da4a64c..b9dff0e 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -73,6 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __tmp = _M_allocate_and_copy(__n, _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -97,9 +98,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_realloc_insert(end(), std::forward<_Args>(__args)...); @@ -122,9 +125,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == end()) { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else { @@ -157,6 +162,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_MOVE3(__position + 1, end(), __position); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); return __position; } @@ -181,6 +187,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (&__x != this) { + _GLIBCXX_ASAN_ANNOTATE_REINIT; #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { @@ -245,10 +252,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER else if (__n > size()) { std::fill(begin(), end(), __val); + const size_type __add = __n - size(); + _GLIBCXX_ASAN_ANNOTATE_GROW(__add); this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_finish, - __n - size(), __val, - _M_get_Tp_allocator()); + __add, __val, _M_get_Tp_allocator()); + _GLIBCXX_ASAN_ANNOTATE_GREW(__add); } else _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); @@ -284,6 +293,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (__len > capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -300,10 +310,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _ForwardIterator __mid = __first; std::advance(__mid, size()); std::copy(__first, __mid, this->_M_impl._M_start); + const size_type __attribute__((__unused__)) __n = __len - size(); + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_copy_a(__mid, __last, this->_M_impl._M_finish, _M_get_Tp_allocator()); + _GLIBCXX_ASAN_ANNOTATE_GREW(__n); } } @@ -317,9 +330,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == cend()) { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::move(__v)); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_insert_aux(begin() + __n, std::move(__v)); @@ -340,9 +355,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == cend()) { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else { @@ -370,10 +387,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_insert_aux(iterator __position, const _Tp& __x) #endif { + _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, - _GLIBCXX_MOVE(*(this->_M_impl._M_finish - - 1))); + _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1))); ++this->_M_impl._M_finish; + _GLIBCXX_ASAN_ANNOTATE_GREW(1); #if __cplusplus < 201103L _Tp __x_copy = __x; #endif @@ -443,11 +461,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, - this->_M_impl._M_end_of_storage - - this->_M_impl._M_start); + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; @@ -473,11 +491,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; + _GLIBCXX_ASAN_ANNOTATE_GREW(__n); _GLIBCXX_MOVE_BACKWARD3(__position.base(), __old_finish - __n, __old_finish); std::fill(__position.base(), __position.base() + __n, @@ -485,15 +505,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } else { + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_finish, __n - __elems_after, __x_copy, _M_get_Tp_allocator()); + _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __elems_after; + _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); std::fill(__position.base(), __old_finish, __x_copy); } } @@ -536,6 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -559,9 +583,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_default_n_a(this->_M_impl._M_finish, __n, _M_get_Tp_allocator()); + _GLIBCXX_ASAN_ANNOTATE_GREW(__n); } else { @@ -587,6 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -606,6 +633,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (capacity() == size()) return false; + _GLIBCXX_ASAN_ANNOTATE_REINIT; return std::__shrink_to_fit_aux::_S_do_it(*this); } #endif @@ -648,11 +676,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; + _GLIBCXX_ASAN_ANNOTATE_GREW(__n); _GLIBCXX_MOVE_BACKWARD3(__position.base(), __old_finish - __n, __old_finish); std::copy(__first, __last, __position); @@ -661,15 +691,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _ForwardIterator __mid = __first; std::advance(__mid, __elems_after); + _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_copy_a(__mid, __last, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n - __elems_after; + _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __elems_after; + _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); std::copy(__first, __mid, __position); } } @@ -701,6 +734,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -909,4 +943,9 @@ _GLIBCXX_END_NAMESPACE_VERSION #endif // C++11 +#undef _GLIBCXX_ASAN_ANNOTATE_REINIT +#undef _GLIBCXX_ASAN_ANNOTATE_GROW +#undef _GLIBCXX_ASAN_ANNOTATE_GREW +#undef _GLIBCXX_ASAN_ANNOTATE_SHRINK + #endif /* _VECTOR_TCC */ -- 2.7.4