mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 12:10:39 +08:00
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
This commit is contained in:
parent
5c2dee6fc9
commit
8c7331c556
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<T, std::allocator<T>></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">
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user