Skip to content

Commit ab38ba7

Browse files
committed
[libc++] Refactor vector's ASan annotations to only ever delete and add the annotations
1 parent d7eade1 commit ab38ba7

File tree

2 files changed

+47
-60
lines changed

2 files changed

+47
-60
lines changed

libcxx/include/__utility/scope_guard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class __scope_guard {
3737
// C++14 doesn't have mandatory RVO, so we have to provide a declaration even though no compiler will ever generate
3838
// a call to the move constructor.
3939
#if _LIBCPP_STD_VER <= 14
40+
_LIBCPP_DIAGNOSTIC_PUSH
41+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wundefined-internal")
4042
__scope_guard(__scope_guard&&);
43+
_LIBCPP_DIAGNOSTIC_POP
4144
#else
4245
__scope_guard(__scope_guard&&) = delete;
4346
#endif

libcxx/include/__vector/vector.h

Lines changed: 44 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include <__utility/is_pointer_in_range.h>
6565
#include <__utility/move.h>
6666
#include <__utility/pair.h>
67+
#include <__utility/scope_guard.h>
6768
#include <__utility/swap.h>
6869
#include <initializer_list>
6970
#include <limits>
@@ -481,9 +482,10 @@ class vector {
481482
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity(_Args&&... __args) {
482483
_LIBCPP_ASSERT_INTERNAL(
483484
size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector");
484-
_ConstructTransaction __tx(*this, 1);
485-
__alloc_traits::construct(this->__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);
486-
++__tx.__pos_;
485+
__annotate_delete();
486+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
487+
__alloc_traits::construct(this->__alloc_, std::__to_address(__end_), std::forward<_Args>(__args)...);
488+
++__end_;
487489
}
488490

489491
#if _LIBCPP_STD_VER >= 23
@@ -550,9 +552,9 @@ class vector {
550552
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
551553

552554
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
553-
size_type __old_size = size();
555+
__annotate_delete();
556+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
554557
__base_destruct_at_end(this->__begin_);
555-
__annotate_shrink(__old_size);
556558
}
557559

558560
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
@@ -601,7 +603,7 @@ class vector {
601603

602604
if (__n > 0) {
603605
__vallocate(__n);
604-
__construct_at_end(std::move(__first), std::move(__last), __n);
606+
__construct_at_end(std::move(__first), std::move(__last));
605607
}
606608

607609
__guard.__complete();
@@ -661,8 +663,7 @@ class vector {
661663
__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
662664

663665
template <class _InputIterator, class _Sentinel>
664-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
665-
__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
666+
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIterator __first, _Sentinel __last);
666667

667668
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
668669
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
@@ -710,9 +711,9 @@ class vector {
710711
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type)
711712
_NOEXCEPT_(__alloc_traits::is_always_equal::value);
712713
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
713-
size_type __old_size = size();
714+
__annotate_delete();
715+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
714716
__base_destruct_at_end(__new_last);
715-
__annotate_shrink(__old_size);
716717
}
717718

718719
template <class... _Args>
@@ -739,33 +740,11 @@ class vector {
739740
__annotate_contiguous_container(data() + size(), data() + capacity());
740741
}
741742

742-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT {
743-
__annotate_contiguous_container(data() + size(), data() + size() + __n);
744-
}
745-
746-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT {
747-
__annotate_contiguous_container(data() + __old_size, data() + size());
748-
}
749-
750-
struct _ConstructTransaction {
751-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(vector& __v, size_type __n)
752-
: __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
753-
__v_.__annotate_increase(__n);
754-
}
755-
756-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() {
757-
__v_.__end_ = __pos_;
758-
if (__pos_ != __new_end_) {
759-
__v_.__annotate_shrink(__new_end_ - __v_.__begin_);
760-
}
761-
}
762-
763-
vector& __v_;
764-
pointer __pos_;
765-
const_pointer const __new_end_;
743+
struct __annotate_new_size {
744+
vector& __vec_;
766745

767-
_ConstructTransaction(_ConstructTransaction const&) = delete;
768-
_ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
746+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __annotate_new_size(vector& __vec) : __vec_(__vec) {}
747+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() { __vec_.__annotate_new(__vec_.size()); }
769748
};
770749

771750
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT {
@@ -870,6 +849,7 @@ template <class _Tp, class _Allocator>
870849
_LIBCPP_CONSTEXPR_SINCE_CXX20 void
871850
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
872851
__annotate_delete();
852+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
873853
auto __new_begin = __v.begin() - size();
874854
std::__uninitialized_allocator_relocate(
875855
this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_), std::__to_address(__new_begin));
@@ -878,7 +858,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
878858

879859
__swap_layouts(__v);
880860
__v.__set_data(__v.begin());
881-
__annotate_new(size());
882861
}
883862

884863
// __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
@@ -889,6 +868,7 @@ template <class _Tp, class _Allocator>
889868
_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
890869
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
891870
__annotate_delete();
871+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
892872
pointer __ret = __v.begin();
893873

894874
// Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
@@ -906,7 +886,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
906886
__end_ = __begin_; // All the objects have been destroyed by relocating them.
907887
__swap_layouts(__v);
908888
__v.__set_data(__v.begin());
909-
__annotate_new(size());
910889
return __ret;
911890
}
912891

@@ -940,10 +919,12 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
940919
// Postcondition: size() == size() + __n
941920
template <class _Tp, class _Allocator>
942921
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) {
943-
_ConstructTransaction __tx(*this, __n);
944-
const_pointer __new_end = __tx.__new_end_;
945-
for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
946-
__alloc_traits::construct(this->__alloc_, std::__to_address(__pos));
922+
__annotate_delete();
923+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
924+
925+
for (size_t __i = 0; __i != __n; ++__i) {
926+
__alloc_traits::construct(this->__alloc_, std::__to_address(__end_));
927+
++__end_;
947928
}
948929
}
949930

@@ -956,19 +937,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
956937
template <class _Tp, class _Allocator>
957938
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
958939
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
959-
_ConstructTransaction __tx(*this, __n);
960-
const_pointer __new_end = __tx.__new_end_;
961-
for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
962-
__alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x);
940+
__annotate_delete();
941+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
942+
943+
for (size_t __i = 0; __i != __n; ++__i) {
944+
__alloc_traits::construct(this->__alloc_, std::__to_address(__end_), __x);
945+
++__end_;
963946
}
964947
}
965948

966949
template <class _Tp, class _Allocator>
967950
template <class _InputIterator, class _Sentinel>
968951
_LIBCPP_CONSTEXPR_SINCE_CXX20 void
969-
vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
970-
_ConstructTransaction __tx(*this, __n);
971-
__tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_);
952+
vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last) {
953+
__annotate_delete();
954+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
955+
__end_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __end_);
972956
}
973957

974958
// Default constructs __n objects starting at __end_
@@ -1085,20 +1069,19 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
10851069
if (__new_size > size()) {
10861070
#if _LIBCPP_STD_VER >= 23
10871071
auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
1088-
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
10891072
#else
10901073
_Iterator __mid = std::next(__first, size());
10911074
std::copy(__first, __mid, this->__begin_);
1092-
__construct_at_end(__mid, __last, __new_size - size());
10931075
#endif
1076+
__construct_at_end(std::move(__mid), std::move(__last));
10941077
} else {
10951078
pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
10961079
this->__destruct_at_end(__m);
10971080
}
10981081
} else {
10991082
__vdeallocate();
11001083
__vallocate(__recommend(__new_size));
1101-
__construct_at_end(std::move(__first), std::move(__last), __new_size);
1084+
__construct_at_end(std::move(__first), std::move(__last));
11021085
}
11031086
}
11041087

@@ -1227,15 +1210,16 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
12271210
template <class _Tp, class _Allocator>
12281211
_LIBCPP_CONSTEXPR_SINCE_CXX20 void
12291212
vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) {
1213+
__annotate_delete();
1214+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
12301215
pointer __old_last = this->__end_;
12311216
difference_type __n = __old_last - __to;
1232-
{
1233-
pointer __i = __from_s + __n;
1234-
_ConstructTransaction __tx(*this, __from_e - __i);
1235-
for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) {
1236-
__alloc_traits::construct(this->__alloc_, std::__to_address(__pos), std::move(*__i));
1237-
}
1217+
1218+
for (pointer __i = __from_s + __n; __i != __from_e; ++__i) {
1219+
__alloc_traits::construct(this->__alloc_, std::__to_address(__end_), std::move(*__i));
1220+
++__end_;
12381221
}
1222+
12391223
std::move_backward(__from_s, __from_s + __n, __old_last);
12401224
}
12411225

@@ -1376,13 +1360,13 @@ vector<_Tp, _Allocator>::__insert_with_size(
13761360
if (__n > __dx) {
13771361
#if _LIBCPP_STD_VER >= 23
13781362
if constexpr (!forward_iterator<_Iterator>) {
1379-
__construct_at_end(std::move(__first), std::move(__last), __n);
1363+
__construct_at_end(std::move(__first), std::move(__last));
13801364
std::rotate(__p, __old_last, this->__end_);
13811365
} else
13821366
#endif
13831367
{
13841368
_Iterator __m = std::next(__first, __dx);
1385-
__construct_at_end(__m, __last, __n - __dx);
1369+
__construct_at_end(__m, __last);
13861370
if (__dx > 0) {
13871371
__move_range(__p, __old_last, __p + __n);
13881372
__insert_assign_n_unchecked(__first, __dx, __p);

0 commit comments

Comments
 (0)