diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-12-11 03:41:12 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-12-11 03:41:12 +0000 |
commit | 1286bc577f70c5b8caa83b2440484fbbb3b15a6e (patch) | |
tree | 98844f59716c7a4843315020a26019dfc474f054 /libcxx/test/support/test_allocator.h | |
parent | b6398818780314c84e796ec1d4b1dbda27ddf554 (diff) | |
download | bcm5719-llvm-1286bc577f70c5b8caa83b2440484fbbb3b15a6e.tar.gz bcm5719-llvm-1286bc577f70c5b8caa83b2440484fbbb3b15a6e.zip |
Fix undefined behavior in container swap tests.
These swap tests were swapping non-POCS non-equal allocators which
is undefined behavior. This patch changes the tests to use allocators
which compare equal. In order to test that the allocators were not
swapped I added an "id" field to test_allocator which does not
participate in equality but does propagate across copies/swaps.
This patch is based off of D26623 which was submitted by STL.
llvm-svn: 289358
Diffstat (limited to 'libcxx/test/support/test_allocator.h')
-rw-r--r-- | libcxx/test/support/test_allocator.h | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h index 04f15abf7fb..e77796b676e 100644 --- a/libcxx/test/support/test_allocator.h +++ b/libcxx/test/support/test_allocator.h @@ -13,6 +13,7 @@ #include <type_traits> #include <new> #include <memory> +#include <utility> #include <cstddef> #include <cstdlib> #include <climits> @@ -46,8 +47,8 @@ template <class T> class test_allocator : public test_alloc_base { - int data_; - + int data_; // participates in equality + int id_; // unique identifier, doesn't participate in equality template <class U> friend class test_allocator; public: @@ -61,13 +62,17 @@ public: template <class U> struct rebind {typedef test_allocator<U> other;}; - test_allocator() TEST_NOEXCEPT : data_(0) {++count;} - explicit test_allocator(int i) TEST_NOEXCEPT : data_(i) {++count;} + test_allocator() TEST_NOEXCEPT : data_(0), id_(0) {++count;} + explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) + {++count;} test_allocator(const test_allocator& a) TEST_NOEXCEPT - : data_(a.data_) {++count;} + : data_(a.data_), id_(a.id_) {++count;} template <class U> test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT - : data_(a.data_) {++count;} - ~test_allocator() TEST_NOEXCEPT {assert(data_ >= 0); --count; data_ = -1;} + : data_(a.data_), id_(a.id_) {++count;} + ~test_allocator() TEST_NOEXCEPT { + assert(data_ >= 0); assert(id_ >= 0); + --count; data_ = -1; id_ = -1; + } pointer address(reference x) const {return &x;} const_pointer address(const_reference x) const {return &x;} pointer allocate(size_type n, const void* = 0) @@ -101,6 +106,9 @@ public: {return x.data_ == y.data_;} friend bool operator!=(const test_allocator& x, const test_allocator& y) {return !(x == y);} + + int get_data() const { return data_; } + int get_id() const { return id_; } }; template <class T> @@ -169,6 +177,7 @@ class test_allocator<void> : public test_alloc_base { int data_; + int id_; template <class U> friend class test_allocator; public: @@ -181,13 +190,16 @@ public: template <class U> struct rebind {typedef test_allocator<U> other;}; - test_allocator() TEST_NOEXCEPT : data_(0) {} - explicit test_allocator(int i) TEST_NOEXCEPT : data_(i) {} + test_allocator() TEST_NOEXCEPT : data_(0), id_(0) {} + explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) {} test_allocator(const test_allocator& a) TEST_NOEXCEPT - : data_(a.data_) {} + : data_(a.data_), id_(a.id_) {} template <class U> test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT - : data_(a.data_) {} - ~test_allocator() TEST_NOEXCEPT {data_ = -1;} + : data_(a.data_), id_(a.id_) {} + ~test_allocator() TEST_NOEXCEPT {data_ = -1; id_ = -1; } + + int get_id() const { return id_; } + int get_data() const { return data_; } friend bool operator==(const test_allocator& x, const test_allocator& y) {return x.data_ == y.data_;} |