summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-07-21 16:05:10 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-07-21 16:05:10 +0000
commit09cc3d83763d20efbe1226bd6d2ae38bf1278fe6 (patch)
tree6043f52919e5b7b0577fcb51573583ea8183b79c /libstdc++-v3
parentcdfd91503929ffb953369f6909a8dca3e42737ab (diff)
downloadgcc-09cc3d83763d20efbe1226bd6d2ae38bf1278fe6.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@250430 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog23
-rw-r--r--libstdc++-v3/config/allocator/malloc_allocator_base.h4
-rw-r--r--libstdc++-v3/config/allocator/new_allocator_base.h4
-rw-r--r--libstdc++-v3/doc/xml/manual/using.xml18
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h146
-rw-r--r--libstdc++-v3/include/bits/vector.tcc51
6 files changed, 234 insertions, 12 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d60c5705486..6d827669d9a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,26 @@
+2017-07-20 Jonathan Wakely <jwakely@redhat.com>
+
+ * 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 <jwakely@redhat.com>
PR libstdc++/81476
diff --git a/libstdc++-v3/config/allocator/malloc_allocator_base.h b/libstdc++-v3/config/allocator/malloc_allocator_base.h
index b091bbca863..54e0837f01f 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 3d2bb67887f..e776ed31864 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 5c0e1b9f8c1..6ce29fd30be 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
</listitem></varlistentry>
</variablelist>
+ <varlistentry><term><code>_GLIBCXX_SANITIZE_VECTOR</code></term>
+ <listitem>
+ <para>
+ Undefined by default. When defined, <classname>std::vector</classname>
+ operations will be annotated so that AddressSanitizer can detect
+ invalid accesses to the unused capacity of a
+ <classname>std::vector</classname>. These annotations are only
+ enabled for
+ <classname>std::vector&lt;T, std::allocator&lt;T&gt;&gt;</classname>
+ and only when <classname>std::allocator</classname> is derived from
+ <xref linkend="allocator.impl"><classname>new_allocator</classname>
+ or <classname>malloc_allocator</classname></xref>. 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.
+ </para>
+ </listitem></varlistentry>
+
</section>
<section xml:id="manual.intro.using.abi" xreflabel="Dual ABI">
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 7ee3ce96890..c7787f72ff5 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -65,6 +65,12 @@
#include <debug/assertions.h>
+#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<typename = _Tp_alloc_type>
+ 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<typename _Up>
+ struct _Asan<allocator<_Up> >
+ {
+ 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 da4a64cbd1f..b9dff0e80df 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<vector>::_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 */