From 1f50f2d64baeb8130e1f47c379c12ee5d2400b72 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 8 May 2014 14:14:06 +0000 Subject: [PATCH] Add Address Sanitizer support to std::vector git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@208319 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 5 ++ include/vector | 55 +++++++++++++++++++ .../containers/sequences/vector/asan.pass.cpp | 52 ++++++++++++++++++ .../vector/vector.capacity/capacity.pass.cpp | 5 ++ .../vector/vector.capacity/reserve.pass.cpp | 6 ++ .../vector.capacity/resize_size.pass.cpp | 11 ++++ .../resize_size_value.pass.cpp | 7 +++ .../vector.capacity/shrink_to_fit.pass.cpp | 9 +++ .../vector/vector.capacity/swap.pass.cpp | 9 +++ .../assign_initializer_list.pass.cpp | 3 + .../vector/vector.cons/assign_move.pass.cpp | 19 +++++++ .../vector.cons/construct_default.pass.cpp | 4 ++ .../vector.cons/construct_iter_iter.pass.cpp | 2 + .../construct_iter_iter_alloc.pass.cpp | 2 + .../vector.cons/construct_size.pass.cpp | 3 + .../vector.cons/construct_size_value.pass.cpp | 2 + .../construct_size_value_alloc.pass.cpp | 2 + .../vector/vector.cons/copy.pass.cpp | 14 +++++ .../vector/vector.cons/copy_alloc.pass.cpp | 2 + .../vector.cons/initializer_list.pass.cpp | 3 + .../initializer_list_alloc.pass.cpp | 3 + .../vector/vector.cons/move.pass.cpp | 22 ++++++++ .../vector/vector.cons/move_alloc.pass.cpp | 21 +++++++ .../op_equal_initializer_list.pass.cpp | 3 + .../vector/vector.data/data.pass.cpp | 5 ++ .../vector/vector.data/data_const.pass.cpp | 5 ++ .../vector/vector.modifiers/emplace.pass.cpp | 7 +++ .../vector.modifiers/emplace_back.pass.cpp | 7 +++ .../vector.modifiers/emplace_extra.pass.cpp | 9 +++ .../vector.modifiers/erase_iter.pass.cpp | 9 +++ .../vector.modifiers/erase_iter_iter.pass.cpp | 29 ++++++++++ .../insert_iter_initializer_list.pass.cpp | 3 + .../insert_iter_iter_iter.pass.cpp | 7 +++ .../insert_iter_rvalue.pass.cpp | 4 ++ .../insert_iter_size_value.pass.cpp | 5 ++ .../insert_iter_value.pass.cpp | 4 ++ .../vector.modifiers/push_back.pass.cpp | 16 ++++++ .../push_back_exception_safety.pass.cpp | 5 ++ .../push_back_rvalue.pass.cpp | 16 ++++++ .../vector/vector.special/swap.pass.cpp | 41 ++++++++++++++ test/support/asan_testing.h | 37 +++++++++++++ 41 files changed, 473 insertions(+) create mode 100644 test/containers/sequences/vector/asan.pass.cpp create mode 100644 test/support/asan_testing.h diff --git a/include/__config b/include/__config index fb775c6bd..ce39243c0 100644 --- a/include/__config +++ b/include/__config @@ -629,6 +629,11 @@ template struct __static_assert_check {}; #define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] #endif +#ifndef _LIBCPP_HAS_NO_ASAN +extern "C" void __sanitizer_annotate_contiguous_container( + const void *, const void *, const void *, const void *); +#endif + // Try to find out if RTTI is disabled. // g++ and cl.exe have RTTI on by default and define a macro when it is. // g++ only defines the macro in 4.3.2 and onwards. diff --git a/include/vector b/include/vector index 6ac78d5d5..2cc23e5c6 100644 --- a/include/vector +++ b/include/vector @@ -483,6 +483,7 @@ class _LIBCPP_TYPE_VIS_ONLY vector { private: typedef __vector_base<_Tp, _Allocator> __base; + typedef allocator<_Tp> __default_allocator_type; public: typedef vector __self; typedef _Tp value_type; @@ -749,7 +750,9 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT { + size_type __old_size = size(); __base::clear(); + __annotate_shrink(__old_size); __invalidate_all_iterators(); } @@ -816,7 +819,9 @@ private: } __get_db()->unlock(); #endif + size_type __old_size = size(); __base::__destruct_at_end(__new_last); + __annotate_shrink(__old_size); } template void @@ -830,17 +835,52 @@ private: void __emplace_back_slow_path(_Args&&... __args); #endif + // The following functions are no-ops outside of AddressSanitizer mode. + // We call annotatations only for the default Allocator because other allocators + // may not meet the AddressSanitizer alignment constraints. + // See the documentation for __sanitizer_annotate_contiguous_container for more details. + void __annotate_contiguous_container + (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) + { +#ifndef _LIBCPP_HAS_NO_ASAN + if (__beg && is_same::value) + __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); +#endif + } + + void __annotate_new(size_type __current_size) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + capacity(), data() + __current_size); + } + void __annotate_delete() + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + size(), data() + capacity()); + } + void __annotate_increase(size_type __n) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + size(), data() + size() + __n); + } + void __annotate_shrink(size_type __old_size) + { + __annotate_contiguous_container(data(), data() + capacity(), + data() + __old_size, data() + size()); + } }; template void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v) { + __annotate_delete(); __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); __v.__first_ = __v.__begin_; + __annotate_new(size()); __invalidate_all_iterators(); } @@ -848,6 +888,7 @@ template typename vector<_Tp, _Allocator>::pointer vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer __p) { + __annotate_delete(); pointer __r = __v.__begin_; __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_); __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_); @@ -855,6 +896,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); __v.__first_ = __v.__begin_; + __annotate_new(size()); __invalidate_all_iterators(); return __r; } @@ -874,6 +916,7 @@ vector<_Tp, _Allocator>::allocate(size_type __n) this->__throw_length_error(); this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n); this->__end_cap() = this->__begin_ + __n; + __annotate_new(0); } template @@ -920,6 +963,7 @@ void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) { allocator_type& __a = this->__alloc(); + __annotate_increase(__n); do { __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); @@ -940,6 +984,7 @@ void vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) { allocator_type& __a = this->__alloc(); + __annotate_increase(__n); do { __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); @@ -960,6 +1005,7 @@ vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIt allocator_type& __a = this->__alloc(); for (; __first != __last; ++__first) { + __annotate_increase(1); __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); ++this->__end_; } @@ -972,6 +1018,7 @@ vector<_Tp, _Allocator>::__move_construct_at_end(pointer __first, pointer __last allocator_type& __a = this->__alloc(); for (; __first != __last; ++__first) { + __annotate_increase(1); __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), _VSTD::move(*__first)); ++this->__end_; @@ -1535,6 +1582,7 @@ vector<_Tp, _Allocator>::push_back(const_reference __x) { if (this->__end_ != this->__end_cap()) { + __annotate_increase(1); __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(this->__end_), __x); ++this->__end_; @@ -1552,6 +1600,7 @@ vector<_Tp, _Allocator>::push_back(value_type&& __x) { if (this->__end_ < this->__end_cap()) { + __annotate_increase(1); __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(this->__end_), _VSTD::move(__x)); @@ -1584,6 +1633,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { if (this->__end_ < this->__end_cap()) { + __annotate_increase(1); __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(this->__end_), _VSTD::forward<_Args>(__args)...); @@ -1666,6 +1716,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { + __annotate_increase(1); if (__p == this->__end_) { __alloc_traits::construct(this->__alloc(), @@ -1705,6 +1756,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { + __annotate_increase(1); if (__p == this->__end_) { __alloc_traits::construct(this->__alloc(), @@ -1743,6 +1795,7 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { + __annotate_increase(1); if (__p == this->__end_) { __alloc_traits::construct(this->__alloc(), @@ -1794,6 +1847,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_ } if (__n > 0) { + __annotate_increase(__n); __move_range(__p, __old_last, __p + __old_n); const_pointer __xr = pointer_traits::pointer_to(__x); if (__p <= __xr && __xr < this->__end_) @@ -1904,6 +1958,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi } if (__n > 0) { + __annotate_increase(__n); __move_range(__p, __old_last, __p + __old_n); _VSTD::copy(__first, __m, __p); } diff --git a/test/containers/sequences/vector/asan.pass.cpp b/test/containers/sequences/vector/asan.pass.cpp new file mode 100644 index 000000000..86c02b295 --- /dev/null +++ b/test/containers/sequences/vector/asan.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// reference operator[](size_type n); + +#include +#include +#include + +#include "min_allocator.h" +#include "asan_testing.h" + +#ifndef _LIBCPP_HAS_NO_ASAN +extern "C" void __asan_set_error_exit_code(int); + +int main() +{ +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::vector> C; + const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + C c(std::begin(t), std::end(t)); + c.reserve(2*c.size()); + T foo = c[c.size()]; // bad, but not caught by ASAN + } +#endif + + __asan_set_error_exit_code(0); + { + typedef int T; + typedef std::vector C; + const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + C c(std::begin(t), std::end(t)); + c.reserve(2*c.size()); + assert(is_contiguous_container_asan_correct(c)); + assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity())); + T foo = c[c.size()]; // should trigger ASAN + assert(false); // if we got here, ASAN didn't trigger + } +} +#else +int main () { return 0; } +#endif diff --git a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp index a22c6dae3..21082c839 100644 --- a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp @@ -15,29 +15,34 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { { std::vector v; assert(v.capacity() == 0); + assert(is_contiguous_container_asan_correct(v)); } { std::vector v(100); assert(v.capacity() == 100); v.push_back(0); assert(v.capacity() > 101); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { std::vector> v; assert(v.capacity() == 0); + assert(is_contiguous_container_asan_correct(v)); } { std::vector> v(100); assert(v.capacity() == 100); v.push_back(0); assert(v.capacity() > 101); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp index 2914af91a..4df5702f2 100644 --- a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -15,6 +15,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -22,6 +23,7 @@ int main() std::vector v; v.reserve(10); assert(v.capacity() >= 10); + assert(is_contiguous_container_asan_correct(v)); } { std::vector v(100); @@ -32,6 +34,7 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); + assert(is_contiguous_container_asan_correct(v)); } { std::vector > v(100); @@ -42,12 +45,14 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { std::vector> v; v.reserve(10); assert(v.capacity() >= 10); + assert(is_contiguous_container_asan_correct(v)); } { std::vector> v(100); @@ -58,6 +63,7 @@ int main() v.reserve(150); assert(v.size() == 100); assert(v.capacity() == 150); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp index e415cee04..a47c5131d 100644 --- a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp @@ -16,6 +16,7 @@ #include "../../../stack_allocator.h" #include "../../../MoveOnly.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -25,18 +26,22 @@ int main() v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } { std::vector > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES { @@ -44,18 +49,22 @@ int main() v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } { std::vector > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #if __cplusplus >= 201103L @@ -64,9 +73,11 @@ int main() v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp index 49f373a09..de5126b03 100644 --- a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp @@ -15,6 +15,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -27,6 +28,7 @@ int main() v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); for (unsigned i = 0; i < 50; ++i) assert(v[i] == 0); for (unsigned i = 50; i < 200; ++i) @@ -40,6 +42,7 @@ int main() v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { @@ -47,10 +50,12 @@ int main() v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); assert((v == std::vector>(50))); v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); for (unsigned i = 0; i < 50; ++i) assert(v[i] == 0); for (unsigned i = 50; i < 200; ++i) @@ -61,9 +66,11 @@ int main() v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); + assert(is_contiguous_container_asan_correct(v)); v.resize(200, 1); assert(v.size() == 200); assert(v.capacity() >= 200); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp index 6b0cce4eb..49ab9cc71 100644 --- a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp @@ -15,39 +15,48 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { { std::vector v(100); v.push_back(1); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); } { std::vector > v(100); v.push_back(1); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); } #ifndef _LIBCPP_NO_EXCEPTIONS { std::vector > v(100); v.push_back(1); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 200); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); } #endif #if __cplusplus >= 201103L { std::vector> v(100); v.push_back(1); + assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); assert(v.capacity() == 101); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp index 46d84033a..f3d9289c3 100644 --- a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp +++ b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp @@ -15,27 +15,36 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { { std::vector v1(100); std::vector v2(200); + assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v2)); v1.swap(v2); assert(v1.size() == 200); assert(v1.capacity() == 200); + assert(is_contiguous_container_asan_correct(v1)); assert(v2.size() == 100); assert(v2.capacity() == 100); + assert(is_contiguous_container_asan_correct(v2)); } #if __cplusplus >= 201103L { std::vector> v1(100); std::vector> v2(200); + assert(is_contiguous_container_asan_correct(v1)); + assert(is_contiguous_container_asan_correct(v2)); v1.swap(v2); assert(v1.size() == 200); assert(v1.capacity() == 200); + assert(is_contiguous_container_asan_correct(v1)); assert(v2.size() == 100); assert(v2.capacity() == 100); + assert(is_contiguous_container_asan_correct(v2)); } #endif } diff --git a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp index c0dafce02..f5c06b1a1 100644 --- a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp @@ -15,6 +15,7 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -23,6 +24,7 @@ int main() std::vector d; d.assign({3, 4, 5, 6}); assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); @@ -33,6 +35,7 @@ int main() std::vector> d; d.assign({3, 4, 5, 6}); assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp index 1365038cb..d87ac8636 100644 --- a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp @@ -16,6 +16,7 @@ #include "../../../MoveOnly.h" #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -28,54 +29,72 @@ int main() l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(test_allocator(5)); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector > l(test_allocator(5)); std::vector > lo(test_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(test_allocator(6)); l2 = std::move(l); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == test_allocator(6)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector > l(other_allocator(5)); std::vector > lo(other_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(other_allocator(6)); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } #if __cplusplus >= 201103L { std::vector > l(min_allocator{}); std::vector > lo(min_allocator{}); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(min_allocator{}); l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp index 48c8cf810..75772bef7 100644 --- a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp @@ -18,6 +18,7 @@ #include "../../../NotConstructible.h" #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -27,11 +28,13 @@ test0() assert(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == typename C::allocator_type()); + assert(is_contiguous_container_asan_correct(c)); #if __cplusplus >= 201103L C c1 = {}; assert(c1.__invariants()); assert(c1.empty()); assert(c1.get_allocator() == typename C::allocator_type()); + assert(is_contiguous_container_asan_correct(c1)); #endif } @@ -43,6 +46,7 @@ test1(const typename C::allocator_type& a) assert(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == a); + assert(is_contiguous_container_asan_correct(c)); } int main() diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index 8dde17fb3..36e231acc 100644 --- a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -17,6 +17,7 @@ #include "test_iterators.h" #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -25,6 +26,7 @@ test(Iterator first, Iterator last) C c(first, last); assert(c.__invariants()); assert(c.size() == std::distance(first, last)); + assert(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); } diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp index 9edc10c80..7fa748a90 100644 --- a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -18,6 +18,7 @@ #include "test_iterators.h" #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -26,6 +27,7 @@ test(Iterator first, Iterator last, const A& a) C c(first, last, a); assert(c.__invariants()); assert(c.size() == std::distance(first, last)); + assert(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first) assert(*i == *first); } diff --git a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp index c6bbf6eca..e03389593 100644 --- a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp @@ -17,6 +17,7 @@ #include "DefaultOnly.h" #include "min_allocator.h" #include "test_allocator.h" +#include "asan_testing.h" template void @@ -27,6 +28,7 @@ test2(typename C::size_type n, typename C::allocator_type const& a = typename C: assert(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == a); + assert(is_contiguous_container_asan_correct(c)); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == typename C::value_type()); @@ -42,6 +44,7 @@ test1(typename C::size_type n) assert(c.__invariants()); assert(c.size() == n); assert(c.get_allocator() == typename C::allocator_type()); + assert(is_contiguous_container_asan_correct(c)); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == typename C::value_type()); diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp index 6a52d52af..5b6c49857 100644 --- a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp @@ -16,6 +16,7 @@ #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -24,6 +25,7 @@ test(typename C::size_type n, const typename C::value_type& x) C c(n, x); assert(c.__invariants()); assert(c.size() == n); + assert(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == x); } diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp index 5653521f2..c62b84104 100644 --- a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp @@ -14,6 +14,7 @@ #include #include #include "min_allocator.h" +#include "asan_testing.h" template void @@ -24,6 +25,7 @@ test(typename C::size_type n, const typename C::value_type& x, assert(c.__invariants()); assert(a == c.get_allocator()); assert(c.size() == n); + assert(is_contiguous_container_asan_correct(c)); for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i) assert(*i == x); } diff --git a/test/containers/sequences/vector/vector.cons/copy.pass.cpp b/test/containers/sequences/vector/vector.cons/copy.pass.cpp index 6962f7035..677963dee 100644 --- a/test/containers/sequences/vector/vector.cons/copy.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/copy.pass.cpp @@ -15,6 +15,7 @@ #include #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -25,6 +26,7 @@ test(const C& x) assert(c.__invariants()); assert(c.size() == s); assert(c == x); + assert(is_contiguous_container_asan_correct(c)); } int main() @@ -37,15 +39,23 @@ int main() { std::vector > v(3, 2, test_allocator(5)); std::vector > v2 = v; + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE { std::vector > v(3, 2, other_allocator(5)); std::vector > v2 = v; + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == other_allocator(-2)); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE #if __cplusplus >= 201103L @@ -57,8 +67,12 @@ int main() { std::vector > v(3, 2, min_allocator()); std::vector > v2 = v; + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); assert(v2 == v); assert(v2.get_allocator() == v.get_allocator()); + assert(is_contiguous_container_asan_correct(v)); + assert(is_contiguous_container_asan_correct(v2)); } #endif } diff --git a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp index 7ff2a1e17..128328c2a 100644 --- a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp @@ -15,6 +15,7 @@ #include #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" template void @@ -25,6 +26,7 @@ test(const C& x, const typename C::allocator_type& a) assert(c.__invariants()); assert(c.size() == s); assert(c == x); + assert(is_contiguous_container_asan_correct(c)); } int main() diff --git a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp index f231fcf8a..7eb834ff3 100644 --- a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp @@ -14,6 +14,7 @@ #include #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -21,6 +22,7 @@ int main() { std::vector d = {3, 4, 5, 6}; assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); @@ -30,6 +32,7 @@ int main() { std::vector> d = {3, 4, 5, 6}; assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp index b57d2ed17..5d7ae884e 100644 --- a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp @@ -16,6 +16,7 @@ #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -24,6 +25,7 @@ int main() std::vector> d({3, 4, 5, 6}, test_allocator(3)); assert(d.get_allocator() == test_allocator(3)); assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); @@ -34,6 +36,7 @@ int main() std::vector> d({3, 4, 5, 6}, min_allocator()); assert(d.get_allocator() == min_allocator()); assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/containers/sequences/vector/vector.cons/move.pass.cpp b/test/containers/sequences/vector/vector.cons/move.pass.cpp index f09e3467a..bb61d5494 100644 --- a/test/containers/sequences/vector/vector.cons/move.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/move.pass.cpp @@ -16,6 +16,7 @@ #include "../../../MoveOnly.h" #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -23,58 +24,79 @@ int main() { std::vector > l(test_allocator(5)); std::vector > lo(test_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector > l(other_allocator(5)); std::vector > lo(other_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } { int a1[] = {1, 3, 7, 9, 10}; std::vector c1(a1, a1+sizeof(a1)/sizeof(a1[0])); + assert(is_contiguous_container_asan_correct(c1)); std::vector::const_iterator i = c1.begin(); std::vector c2 = std::move(c1); + assert(is_contiguous_container_asan_correct(c2)); std::vector::iterator j = c2.erase(i); assert(*j == 3); + assert(is_contiguous_container_asan_correct(c2)); } #if __cplusplus >= 201103L { std::vector > l(min_allocator{}); std::vector > lo(min_allocator{}); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2 = std::move(l); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } { int a1[] = {1, 3, 7, 9, 10}; std::vector> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); + assert(is_contiguous_container_asan_correct(c1)); std::vector>::const_iterator i = c1.begin(); std::vector> c2 = std::move(c1); + assert(is_contiguous_container_asan_correct(c2)); std::vector>::iterator j = c2.erase(i); assert(*j == 3); + assert(is_contiguous_container_asan_correct(c2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp index 0aac64dc0..1923e68f7 100644 --- a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp @@ -16,6 +16,7 @@ #include "../../../MoveOnly.h" #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -23,55 +24,75 @@ int main() { std::vector > l(test_allocator(5)); std::vector > lo(test_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(std::move(l), test_allocator(6)); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == test_allocator(6)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector > l(test_allocator(5)); std::vector > lo(test_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(std::move(l), test_allocator(5)); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == test_allocator(5)); + assert(is_contiguous_container_asan_correct(l2)); } { std::vector > l(other_allocator(5)); std::vector > lo(other_allocator(5)); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(std::move(l), other_allocator(4)); assert(l2 == lo); assert(!l.empty()); assert(l2.get_allocator() == other_allocator(4)); + assert(is_contiguous_container_asan_correct(l2)); } #if __cplusplus >= 201103L { std::vector > l(min_allocator{}); std::vector > lo(min_allocator{}); + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); for (int i = 1; i <= 3; ++i) { l.push_back(i); lo.push_back(i); } + assert(is_contiguous_container_asan_correct(l)); + assert(is_contiguous_container_asan_correct(lo)); std::vector > l2(std::move(l), min_allocator()); assert(l2 == lo); assert(l.empty()); assert(l2.get_allocator() == min_allocator()); + assert(is_contiguous_container_asan_correct(l2)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp index 13ec845ec..592b71462 100644 --- a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp @@ -15,6 +15,7 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -23,6 +24,7 @@ int main() std::vector d; d = {3, 4, 5, 6}; assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); @@ -33,6 +35,7 @@ int main() std::vector> d; d = {3, 4, 5, 6}; assert(d.size() == 4); + assert(is_contiguous_container_asan_correct(d)); assert(d[0] == 3); assert(d[1] == 4); assert(d[2] == 5); diff --git a/test/containers/sequences/vector/vector.data/data.pass.cpp b/test/containers/sequences/vector/vector.data/data.pass.cpp index 4bda599a8..aed56bc09 100644 --- a/test/containers/sequences/vector/vector.data/data.pass.cpp +++ b/test/containers/sequences/vector/vector.data/data.pass.cpp @@ -15,25 +15,30 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { { std::vector v; assert(v.data() == 0); + assert(is_contiguous_container_asan_correct(v)); } { std::vector v(100); assert(v.data() == &v.front()); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { std::vector> v; assert(v.data() == 0); + assert(is_contiguous_container_asan_correct(v)); } { std::vector> v(100); assert(v.data() == &v.front()); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.data/data_const.pass.cpp b/test/containers/sequences/vector/vector.data/data_const.pass.cpp index 7cb64f85d..cb6062694 100644 --- a/test/containers/sequences/vector/vector.data/data_const.pass.cpp +++ b/test/containers/sequences/vector/vector.data/data_const.pass.cpp @@ -15,25 +15,30 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { { const std::vector v; assert(v.data() == 0); + assert(is_contiguous_container_asan_correct(v)); } { const std::vector v(100); assert(v.data() == &v.front()); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { const std::vector> v; assert(v.data() == 0); + assert(is_contiguous_container_asan_correct(v)); } { const std::vector> v(100); assert(v.data() == &v.front()); + assert(is_contiguous_container_asan_correct(v)); } #endif } diff --git a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp index 37298a534..8af6bdacd 100644 --- a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp @@ -19,6 +19,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -66,6 +67,7 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cend(), 3, 4.5); assert(i == c.end()-1); assert(c.size() == 2); @@ -73,6 +75,7 @@ int main() assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cbegin()+1, 4, 6.5); assert(i == c.begin()+1); assert(c.size() == 3); @@ -82,6 +85,7 @@ int main() assert(c[1].getd() == 6.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); } { std::vector > c; @@ -90,6 +94,7 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cend(), 3, 4.5); assert(i == c.end()-1); assert(c.size() == 2); @@ -97,6 +102,7 @@ int main() assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); i = c.emplace(c.cbegin()+1, 4, 6.5); assert(i == c.begin()+1); assert(c.size() == 3); @@ -106,6 +112,7 @@ int main() assert(c[1].getd() == 6.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); } #if _LIBCPP_DEBUG >= 1 { diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp index a399433ce..bbf91a425 100644 --- a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp @@ -15,6 +15,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -61,12 +62,14 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); } { std::vector > c; @@ -74,12 +77,14 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); } #if __cplusplus >= 201103L { @@ -88,12 +93,14 @@ int main() assert(c.size() == 1); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); + assert(is_contiguous_container_asan_correct(c)); c.emplace_back(3, 4.5); assert(c.size() == 2); assert(c.front().geti() == 2); assert(c.front().getd() == 3.5); assert(c.back().geti() == 3); assert(c.back().getd() == 4.5); + assert(is_contiguous_container_asan_correct(c)); } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp index 04ff22831..85a47073b 100644 --- a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp @@ -15,6 +15,7 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -22,31 +23,39 @@ int main() { std::vector v; v.reserve(3); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); + assert(is_contiguous_container_asan_correct(v)); } { std::vector v; v.reserve(4); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); + assert(is_contiguous_container_asan_correct(v)); } #if __cplusplus >= 201103L { std::vector> v; v.reserve(3); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); + assert(is_contiguous_container_asan_correct(v)); } { std::vector> v; v.reserve(4); + assert(is_contiguous_container_asan_correct(v)); v = { 1, 2, 3 }; v.emplace(v.begin(), v.back()); assert(v[0] == 3); + assert(is_contiguous_container_asan_correct(v)); } #endif #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp index fb9d8084f..7a850edda 100644 --- a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp @@ -15,6 +15,7 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -22,6 +23,7 @@ int main() int a1[] = {1, 2, 3}; std::vector l1(a1, a1+3); std::vector::const_iterator i = l1.begin(); + assert(is_contiguous_container_asan_correct(l1)); ++i; std::vector::iterator j = l1.erase(i); assert(l1.size() == 2); @@ -29,21 +31,25 @@ int main() assert(*j == 3); assert(*l1.begin() == 1); assert(*next(l1.begin()) == 3); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(j); assert(j == l1.end()); assert(l1.size() == 1); assert(distance(l1.begin(), l1.end()) == 1); assert(*l1.begin() == 1); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(l1.begin()); assert(j == l1.end()); assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); + assert(is_contiguous_container_asan_correct(l1)); } #if __cplusplus >= 201103L { int a1[] = {1, 2, 3}; std::vector> l1(a1, a1+3); std::vector>::const_iterator i = l1.begin(); + assert(is_contiguous_container_asan_correct(l1)); ++i; std::vector>::iterator j = l1.erase(i); assert(l1.size() == 2); @@ -51,15 +57,18 @@ int main() assert(*j == 3); assert(*l1.begin() == 1); assert(*next(l1.begin()) == 3); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(j); assert(j == l1.end()); assert(l1.size() == 1); assert(distance(l1.begin(), l1.end()) == 1); assert(*l1.begin() == 1); + assert(is_contiguous_container_asan_correct(l1)); j = l1.erase(l1.begin()); assert(j == l1.end()); assert(l1.size() == 0); assert(distance(l1.begin(), l1.end()) == 0); + assert(is_contiguous_container_asan_correct(l1)); } #endif } diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp index e82d3a0dd..bfc18bc48 100644 --- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp @@ -15,84 +15,113 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { int a1[] = {1, 2, 3}; { std::vector l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); assert(l1.size() == 3); assert(distance(l1.cbegin(), l1.cend()) == 3); assert(i == l1.begin()); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin())); assert(l1.size() == 2); assert(distance(l1.cbegin(), l1.cend()) == 2); assert(i == l1.begin()); assert(l1 == std::vector(a1+1, a1+3)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2)); assert(l1.size() == 1); assert(distance(l1.cbegin(), l1.cend()) == 1); assert(i == l1.begin()); assert(l1 == std::vector(a1+2, a1+3)); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3)); assert(l1.size() == 0); assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector > outer(2, std::vector(1)); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); outer.erase(outer.begin(), outer.begin()); assert(outer.size() == 2); assert(outer[0].size() == 1); assert(outer[1].size() == 1); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); } #if __cplusplus >= 201103L { std::vector> l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector>::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); assert(l1.size() == 3); assert(distance(l1.cbegin(), l1.cend()) == 3); assert(i == l1.begin()); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector> l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin())); assert(l1.size() == 2); assert(distance(l1.cbegin(), l1.cend()) == 2); assert(i == l1.begin()); assert((l1 == std::vector>(a1+1, a1+3))); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector> l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2)); assert(l1.size() == 1); assert(distance(l1.cbegin(), l1.cend()) == 1); assert(i == l1.begin()); assert((l1 == std::vector>(a1+2, a1+3))); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector> l1(a1, a1+3); + assert(is_contiguous_container_asan_correct(l1)); std::vector>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3)); assert(l1.size() == 0); assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); + assert(is_contiguous_container_asan_correct(l1)); } { std::vector>, min_allocator>>> outer(2, std::vector>(1)); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); outer.erase(outer.begin(), outer.begin()); assert(outer.size() == 2); assert(outer[0].size() == 1); assert(outer[1].size() == 1); + assert(is_contiguous_container_asan_correct(outer)); + assert(is_contiguous_container_asan_correct(outer[0])); + assert(is_contiguous_container_asan_correct(outer[1])); } #endif } diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp index 386a4f6b3..30b801788 100644 --- a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp @@ -15,6 +15,7 @@ #include #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -23,6 +24,7 @@ int main() std::vector d(10, 1); std::vector::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6}); assert(d.size() == 14); + assert(is_contiguous_container_asan_correct(d)); assert(i == d.begin() + 2); assert(d[0] == 1); assert(d[1] == 1); @@ -44,6 +46,7 @@ int main() std::vector> d(10, 1); std::vector>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6}); assert(d.size() == 14); + assert(is_contiguous_container_asan_correct(d)); assert(i == d.begin() + 2); assert(d[0] == 1); assert(d[1] == 1); diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp index 97255b0b1..cf24a8714 100644 --- a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp @@ -21,6 +21,7 @@ #include "../../../stack_allocator.h" #include "test_iterators.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -31,6 +32,7 @@ int main() std::vector::iterator i = v.insert(v.cbegin() + 10, input_iterator(a), input_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -47,6 +49,7 @@ int main() std::vector::iterator i = v.insert(v.cbegin() + 10, forward_iterator(a), forward_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -63,6 +66,7 @@ int main() std::vector::iterator i = v.insert(v.cbegin() + 10, input_iterator(a), input_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -79,6 +83,7 @@ int main() std::vector::iterator i = v.insert(v.cbegin() + 10, forward_iterator(a), forward_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -107,6 +112,7 @@ int main() std::vector>::iterator i = v.insert(v.cbegin() + 10, input_iterator(a), input_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -123,6 +129,7 @@ int main() std::vector>::iterator i = v.insert(v.cbegin() + 10, forward_iterator(a), forward_iterator(a+N)); assert(v.size() == 100 + N); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp index 7ceb9332b..cf3715ccb 100644 --- a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp @@ -20,6 +20,7 @@ #include "../../../stack_allocator.h" #include "../../../MoveOnly.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -28,6 +29,7 @@ int main() std::vector v(100); std::vector::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -40,6 +42,7 @@ int main() std::vector > v(100); std::vector >::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -61,6 +64,7 @@ int main() std::vector> v(100); std::vector>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp index 322c9ff71..42effc723 100644 --- a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp @@ -19,6 +19,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -26,6 +27,7 @@ int main() std::vector v(100); std::vector::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -39,6 +41,7 @@ int main() std::vector > v(100); std::vector >::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -61,6 +64,7 @@ int main() std::vector> v(100); std::vector>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -74,6 +78,7 @@ int main() std::vector> v(100); std::vector>::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp index 28c771817..feb74c059 100644 --- a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -19,6 +19,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -26,6 +27,7 @@ int main() std::vector v(100); std::vector::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -38,6 +40,7 @@ int main() std::vector > v(100); std::vector >::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) @@ -60,6 +63,7 @@ int main() std::vector> v(100); std::vector>::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); + assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); int j; for (j = 0; j < 10; ++j) diff --git a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp index 5446b7409..eeeba6242 100644 --- a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp @@ -15,6 +15,7 @@ #include #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -22,22 +23,27 @@ int main() std::vector c; c.push_back(0); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } @@ -45,22 +51,27 @@ int main() std::vector > c; c.push_back(0); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } @@ -69,22 +80,27 @@ int main() std::vector> c; c.push_back(0); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(1); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(2); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(3); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); c.push_back(4); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == j); } diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp index f232743b5..6615a25a6 100644 --- a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp @@ -14,6 +14,8 @@ #include #include +#include "asan_testing.h" + // Flag that makes the copy constructor for CMyClass throw an exception static bool gCopyConstructorShouldThow = false; @@ -70,6 +72,8 @@ int main() vec.push_back(instance); std::vector vec2(vec); + assert(is_contiguous_container_asan_correct(vec)); + assert(is_contiguous_container_asan_correct(vec2)); gCopyConstructorShouldThow = true; try { @@ -77,5 +81,6 @@ int main() } catch (...) { assert(vec==vec2); + assert(is_contiguous_container_asan_correct(vec)); } } diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp index bb1af29d3..be4889312 100644 --- a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp @@ -16,6 +16,7 @@ #include "../../../MoveOnly.h" #include "../../../stack_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -24,22 +25,27 @@ int main() std::vector c; c.push_back(MoveOnly(0)); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } @@ -47,22 +53,27 @@ int main() std::vector > c; c.push_back(MoveOnly(0)); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } @@ -71,22 +82,27 @@ int main() std::vector> c; c.push_back(MoveOnly(0)); assert(c.size() == 1); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(1)); assert(c.size() == 2); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(2)); assert(c.size() == 3); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(3)); assert(c.size() == 4); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); c.push_back(MoveOnly(4)); assert(c.size() == 5); + assert(is_contiguous_container_asan_correct(c)); for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } diff --git a/test/containers/sequences/vector/vector.special/swap.pass.cpp b/test/containers/sequences/vector/vector.special/swap.pass.cpp index a7d0c40d6..27001aef7 100644 --- a/test/containers/sequences/vector/vector.special/swap.pass.cpp +++ b/test/containers/sequences/vector/vector.special/swap.pass.cpp @@ -16,6 +16,7 @@ #include #include "test_allocator.h" #include "min_allocator.h" +#include "asan_testing.h" int main() { @@ -24,40 +25,56 @@ int main() int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1 == std::vector(a2, a2+sizeof(a2)/sizeof(a2[0]))); assert(c2 == std::vector(a1, a1+sizeof(a1)/sizeof(a1[0]))); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector c1(a1, a1); std::vector c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1 == std::vector(a2, a2+sizeof(a2)/sizeof(a2[0]))); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector c2(a2, a2); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2 == std::vector(a1, a1+sizeof(a1)/sizeof(a1[0]))); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector c1(a1, a1); std::vector c2(a2, a2); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #ifndef _LIBCPP_DEBUG_LEVEL // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 @@ -80,11 +97,15 @@ int main() typedef other_allocator A; std::vector c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A(1)); std::vector c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(2)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c1.get_allocator() == A(2)); assert((c2 == std::vector(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A(1)); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #if __cplusplus >= 201103L { @@ -92,40 +113,56 @@ int main() int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert((c2 == std::vector>(a1, a1+sizeof(a1)/sizeof(a1[0])))); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector> c1(a1, a1); std::vector> c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector>(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector> c1(a1, a1+sizeof(a1)/sizeof(a1[0])); std::vector> c2(a2, a2); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert((c2 == std::vector>(a1, a1+sizeof(a1)/sizeof(a1[0])))); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; std::vector> c1(a1, a1); std::vector> c2(a2, a2); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert(c1.empty()); assert(distance(c1.begin(), c1.end()) == 0); assert(c2.empty()); assert(distance(c2.begin(), c2.end()) == 0); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #ifndef _LIBCPP_DEBUG_LEVEL // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1 @@ -135,11 +172,15 @@ int main() typedef min_allocator A; std::vector c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A()); std::vector c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A()); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); swap(c1, c2); assert((c1 == std::vector(a2, a2+sizeof(a2)/sizeof(a2[0])))); assert(c1.get_allocator() == A()); assert((c2 == std::vector(a1, a1+sizeof(a1)/sizeof(a1[0])))); assert(c2.get_allocator() == A()); + assert(is_contiguous_container_asan_correct(c1)); + assert(is_contiguous_container_asan_correct(c2)); } #endif #endif diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h new file mode 100644 index 000000000..c8797bde6 --- /dev/null +++ b/test/support/asan_testing.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef ASAN_TESTING_H +#define ASAN_TESTING_H + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_ASAN +extern "C" int __sanitizer_verify_contiguous_container + ( const void *beg, const void *mid, const void *end ); + +template +bool is_contiguous_container_asan_correct ( const std::vector &c ) +{ + if ( std::is_same>::value && c.data() != NULL) + return __sanitizer_verify_contiguous_container ( + c.data(), c.data() + c.size(), c.data() + c.capacity()) != 0; + return true; +} + +#else +template +bool is_contiguous_container_asan_correct ( const std::vector &c ) +{ + return true; +} +#endif + + +#endif // ASAN_TESTING_H \ No newline at end of file