Add AddressSanitizer annotations to std::vector
authorJonathan Wakely <jwakely@redhat.com>
Fri, 21 Jul 2017 16:05:10 +0000 (17:05 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 21 Jul 2017 16:05:10 +0000 (17:05 +0100)
* 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
libstdc++-v3/config/allocator/malloc_allocator_base.h
libstdc++-v3/config/allocator/new_allocator_base.h
libstdc++-v3/doc/xml/manual/using.xml
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc

index d60c570..6d82766 100644 (file)
@@ -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
index b091bbc..54e0837 100644 (file)
@@ -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
index 3d2bb67..e776ed3 100644 (file)
@@ -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
index 5c0e1b9..6ce29fd 100644 (file)
@@ -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">
index 7ee3ce9..c7787f7 100644 (file)
 
 #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
index da4a64c..b9dff0e 100644 (file)
@@ -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 */