From 124ed406e56ed380279a6a05f996a96ff511af9d Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sat, 8 Oct 2016 00:56:22 +0000 Subject: [PATCH] [libc++] Fix stack_allocator Summary: To quote STL the problems with stack allocator are" >"stack_allocator is seriously nonconformant to N4582 17.6.3.5 [allocator.requirements]. > First, it lacks a rebinding constructor. (The nested "struct rebind" isn't sufficient.) > Second, it lacks templated equality/inequality. > Third, it completely ignores alignment. > Finally, and most severely, the Standard forbids its existence. Allocators are forbidden from returning memory "inside themselves". This requirement is implied by the Standard's requirements for rebinding and equality. It's permitted to return memory from a separate buffer object on the stack, though." This patch attempts to address all of those issues. First, instead of storing the buffer inside the allocator I've change `stack_allocator` to accept the buffer as an argument. Second, in order to fix rebinding I changed the parameter list from `` to ``. This allows allocator rebinding between types that have different sizes. Third, I added copy and rebinding constructors and assignment operators. And finally I fixed the allocation logic to always return properly aligned storage. Reviewers: mclow.lists, howard.hinnant, STL_MSFT Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25154 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@283631 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../priqueue.cons/ctor_comp.pass.cpp | 4 +- .../priqueue.cons/ctor_default.pass.cpp | 4 +- .../queue/queue.cons/ctor_default.pass.cpp | 4 +- .../stack/stack.cons/ctor_default.pass.cpp | 4 +- .../deque/deque.cons/default.pass.cpp | 4 +- .../deque/deque.cons/iter_iter.pass.cpp | 4 +- .../sequences/deque/deque.cons/size.pass.cpp | 4 +- .../deque/deque.cons/size_value.pass.cpp | 4 +- .../deque.modifiers/insert_iter_iter.pass.cpp | 4 +- .../list.cons/default_stack_alloc.pass.cpp | 4 +- .../list/list.cons/input_iterator.pass.cpp | 4 +- .../list/list.cons/size_type.pass.cpp | 4 +- .../list/list.cons/size_value_alloc.pass.cpp | 4 +- .../vector/vector.capacity/reserve.pass.cpp | 4 +- .../vector.capacity/resize_size.pass.cpp | 6 +- .../resize_size_value.pass.cpp | 4 +- .../vector.capacity/shrink_to_fit.pass.cpp | 6 +- .../vector.cons/construct_default.pass.cpp | 4 +- .../vector.cons/construct_iter_iter.pass.cpp | 12 +-- .../construct_iter_iter_alloc.pass.cpp | 2 +- .../vector.cons/construct_size_value.pass.cpp | 4 +- .../vector/vector.modifiers/emplace.pass.cpp | 6 +- .../vector.modifiers/emplace_back.pass.cpp | 4 +- .../insert_iter_iter_iter.pass.cpp | 6 +- .../insert_iter_rvalue.pass.cpp | 6 +- .../insert_iter_size_value.pass.cpp | 6 +- .../insert_iter_value.pass.cpp | 6 +- .../vector/vector.modifiers/pop_back.pass.cpp | 2 +- .../vector.modifiers/push_back.pass.cpp | 4 +- .../push_back_rvalue.pass.cpp | 4 +- test/std/containers/stack_allocator.h | 66 ----------------- test/support/test_allocator.h | 73 +++++++++++++++++++ 32 files changed, 142 insertions(+), 135 deletions(-) delete mode 100644 test/std/containers/stack_allocator.h diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp index f543b6379..f435ac306 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp @@ -14,11 +14,11 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" int main() { - std::priority_queue > > q((std::less())); + std::priority_queue > > q((std::less())); assert(q.size() == 0); q.push(1); q.push(2); diff --git a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp index 2bffe80ae..5125a4336 100644 --- a/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp +++ b/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp @@ -14,11 +14,11 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" int main() { - std::priority_queue > > q; + std::priority_queue > > q; assert(q.size() == 0); q.push(1); q.push(2); diff --git a/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp b/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp index e6aadd39d..f4b692236 100644 --- a/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp +++ b/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp @@ -14,11 +14,11 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" int main() { - std::queue > > q; + std::queue > > q; assert(q.size() == 0); q.push(1); q.push(2); diff --git a/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp b/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp index 523cd6811..82e459a4b 100644 --- a/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp +++ b/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp @@ -15,11 +15,11 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" int main() { - std::stack > > q; + std::stack > > q; assert(q.size() == 0); q.push(1); q.push(2); diff --git a/test/std/containers/sequences/deque/deque.cons/default.pass.cpp b/test/std/containers/sequences/deque/deque.cons/default.pass.cpp index 7c42d9e77..127b08609 100644 --- a/test/std/containers/sequences/deque/deque.cons/default.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/default.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "../../../NotConstructible.h" #include "min_allocator.h" @@ -33,7 +33,7 @@ test() int main() { test >(); - test >(); + test >(); #if TEST_STD_VER >= 11 test >(); test >(); diff --git a/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp index 12a7faf68..4b9f8856b 100644 --- a/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "test_iterators.h" #include "min_allocator.h" @@ -55,7 +55,7 @@ int main() test(forward_iterator(ab), forward_iterator(an)); test(bidirectional_iterator(ab), bidirectional_iterator(an)); test(random_access_iterator(ab), random_access_iterator(an)); - test >(ab, an); + test >(ab, an); #if TEST_STD_VER >= 11 test >(ab, an); #endif diff --git a/test/std/containers/sequences/deque/deque.cons/size.pass.cpp b/test/std/containers/sequences/deque/deque.cons/size.pass.cpp index b3fccf667..5b963bea3 100644 --- a/test/std/containers/sequences/deque/deque.cons/size.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/size.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "DefaultOnly.h" #include "min_allocator.h" @@ -98,7 +98,7 @@ int main() test >(4096); test >(4097); - test1 >(4095); + test1 >(4095); #if TEST_STD_VER >= 11 test >(4095); diff --git a/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp b/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp index aeda168d1..626f3e9ee 100644 --- a/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp +++ b/test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" template @@ -44,7 +44,7 @@ int main() test >(4095, 78); test >(4096, 1165); test >(4097, 157); - test >(4095, 90); + test >(4095, 90); #if TEST_STD_VER >= 11 test >(4095, 90); #endif diff --git a/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp index fbe3cb69c..b9d9173b3 100644 --- a/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp +++ b/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp @@ -20,7 +20,7 @@ #include "test_macros.h" #include "test_iterators.h" #include "MoveOnly.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" template @@ -270,7 +270,7 @@ int main() testN >(rng[i], rng[j], rng[k]); testNI >(1500, 2000, 1000); #if TEST_STD_VER >= 11 - test_move > >(); + test_move > >(); #endif } #if TEST_STD_VER >= 11 diff --git a/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp index 4b88580e1..a5ff2b0c2 100644 --- a/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" int main() @@ -29,7 +29,7 @@ int main() assert(std::distance(l.begin(), l.end()) == 0); } { - std::list > l; + std::list > l; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } diff --git a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp index 0dd71d70f..aff138521 100644 --- a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp @@ -15,7 +15,7 @@ #include #include #include "test_iterators.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" int main() @@ -43,7 +43,7 @@ int main() } { int a[] = {0, 1, 2, 3}; - std::list > l(input_iterator(a), + std::list > l(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0]))); assert(l.size() == sizeof(a)/sizeof(a[0])); assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); diff --git a/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index 07b4f14dc..4b298bd92 100644 --- a/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -14,7 +14,7 @@ #include #include #include "DefaultOnly.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" template @@ -48,7 +48,7 @@ int main() assert(*i == 0); } { - std::list > l(3); + std::list > l(3); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); std::list::const_iterator i = l.begin(); diff --git a/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp b/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp index ac7b18ea4..c989d5815 100644 --- a/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp +++ b/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp @@ -14,7 +14,7 @@ #include #include #include "DefaultOnly.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" int main() @@ -42,7 +42,7 @@ int main() assert(*i == 2); } { - std::list > l(3, 2); + std::list > l(3, 2); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); std::list::const_iterator i = l.begin(); diff --git a/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp index d04e43db5..e49210b70 100644 --- a/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -37,7 +37,7 @@ int main() assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + std::vector > v(100); assert(v.capacity() == 100); v.reserve(50); assert(v.size() == 100); diff --git a/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp index ce74cf9b7..4f327052d 100644 --- a/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "MoveOnly.h" #include "min_allocator.h" #include "asan_testing.h" @@ -33,7 +33,7 @@ int main() assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + std::vector > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); @@ -56,7 +56,7 @@ int main() assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + std::vector > v(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); diff --git a/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp index 3e7df3127..22255950f 100644 --- a/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -35,7 +35,7 @@ int main() assert(v[i] == 1); } { - std::vector > v(100); + std::vector > v(100); v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); diff --git a/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp index 10ce33f43..daf9b092f 100644 --- a/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp +++ b/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -29,7 +29,7 @@ int main() assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + std::vector > v(100); v.push_back(1); assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); @@ -39,7 +39,7 @@ int main() } #ifndef _LIBCPP_NO_EXCEPTIONS { - std::vector > v(100); + std::vector > v(100); v.push_back(1); assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); diff --git a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp index 4e6eb00ce..edeae04d7 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" #include "test_allocator.h" #include "../../../NotConstructible.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -71,7 +71,7 @@ int main() (test_allocator(5)); } { - std::vector > v; + std::vector > v; assert(v.empty()); } #if TEST_STD_VER >= 11 diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp index 5542e9105..b0c427073 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -16,7 +16,7 @@ #include "test_macros.h" #include "test_iterators.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -42,11 +42,11 @@ int main() test >(random_access_iterator(a), random_access_iterator(an)); test >(a, an); - test > >(input_iterator(a), input_iterator(an)); - test > >(forward_iterator(a), forward_iterator(an)); - test > >(bidirectional_iterator(a), bidirectional_iterator(an)); - test > >(random_access_iterator(a), random_access_iterator(an)); - test > >(a, an); + test > >(input_iterator(a), input_iterator(an)); + test > >(forward_iterator(a), forward_iterator(an)); + test > >(bidirectional_iterator(a), bidirectional_iterator(an)); + test > >(random_access_iterator(a), random_access_iterator(an)); + test > >(a, an); #if TEST_STD_VER >= 11 test> >(input_iterator(a), input_iterator(an)); test> >(forward_iterator(a), forward_iterator(an)); diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp index 7d6215ba9..08d383d2b 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" #include "test_iterators.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" diff --git a/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp index d3774d1a6..2dbd23dfb 100644 --- a/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp @@ -15,7 +15,7 @@ #include #include "test_macros.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -34,7 +34,7 @@ test(typename C::size_type n, const typename C::value_type& x) int main() { test >(50, 3); - test > >(50, 5); + test > >(50, 5); #if TEST_STD_VER >= 11 test> >(50, 3); #endif diff --git a/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp index 8bcc23979..3011c00ef 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -88,8 +88,8 @@ int main() assert(is_contiguous_container_asan_correct(c)); } { - std::vector > c; - std::vector >::iterator i = c.emplace(c.cbegin(), 2, 3.5); + std::vector > c; + std::vector >::iterator i = c.emplace(c.cbegin(), 2, 3.5); assert(i == c.begin()); assert(c.size() == 1); assert(c.front().geti() == 2); diff --git a/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp index 6b435484d..2fece8c78 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp @@ -15,7 +15,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "test_allocator.h" #include "asan_testing.h" @@ -72,7 +72,7 @@ int main() assert(is_contiguous_container_asan_correct(c)); } { - std::vector > c; + std::vector > c; A& r1 = c.emplace_back(2, 3.5); assert(c.size() == 1); assert(&r1 == &c.back()); diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp index b89530211..6c16726c4 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp @@ -18,7 +18,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "test_iterators.h" #include "min_allocator.h" #include "asan_testing.h" @@ -96,7 +96,7 @@ int main() assert(v[j] == 0); } { - std::vector > v(100); + std::vector > v(100); int a[] = {1, 2, 3, 4, 5}; const int N = sizeof(a)/sizeof(a[0]); std::vector::iterator i = v.insert(v.cbegin() + 10, input_iterator(a), @@ -113,7 +113,7 @@ int main() assert(v[j] == 0); } { - std::vector > v(100); + std::vector > v(100); int a[] = {1, 2, 3, 4, 5}; const int N = sizeof(a)/sizeof(a[0]); std::vector::iterator i = v.insert(v.cbegin() + 10, forward_iterator(a), diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp index e1ad6be05..f300385d8 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "MoveOnly.h" #include "min_allocator.h" #include "asan_testing.h" @@ -39,8 +39,8 @@ int main() assert(v[j] == MoveOnly()); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); + 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); diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp index ed4d6c976..c495c648d 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -70,8 +70,8 @@ int main() assert(v[j] == 0); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, 5, 1); + 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); diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp index ba030e9e3..c8b2d8de9 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -68,8 +68,8 @@ int main() assert(v[j] == 0); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, 1); + 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); diff --git a/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp index c81e41904..ed7f2f983 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #if _LIBCPP_DEBUG >= 1 diff --git a/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp index bef3b9c8d..aa4f83f41 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -48,7 +48,7 @@ int main() assert(c[j] == j); } { - std::vector > c; + std::vector > c; c.push_back(0); assert(c.size() == 1); assert(is_contiguous_container_asan_correct(c)); diff --git a/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp index 64762eb37..c4bc8373f 100644 --- a/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp +++ b/test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp @@ -14,7 +14,7 @@ #include #include #include "MoveOnly.h" -#include "../../../stack_allocator.h" +#include "test_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -50,7 +50,7 @@ int main() assert(c[j] == MoveOnly(j)); } { - std::vector > c; + std::vector > c; c.push_back(MoveOnly(0)); assert(c.size() == 1); assert(is_contiguous_container_asan_correct(c)); diff --git a/test/std/containers/stack_allocator.h b/test/std/containers/stack_allocator.h deleted file mode 100644 index d5fab025c..000000000 --- a/test/std/containers/stack_allocator.h +++ /dev/null @@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 STACK_ALLOCATOR_H -#define STACK_ALLOCATOR_H - -#include -#include - -template -class stack_allocator -{ - char buf_[sizeof(T)*N]; - char* ptr_; -public: - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - template struct rebind {typedef stack_allocator other;}; - - stack_allocator() : ptr_(buf_) {} - -private: - stack_allocator(const stack_allocator&);// = delete; - stack_allocator& operator=(const stack_allocator&);// = delete; - -public: - pointer allocate(size_type n, const void* = 0) - { - if (n > N - (ptr_ - buf_) / sizeof(value_type)) { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw std::bad_alloc(); -#else - std::terminate(); -#endif - } - pointer r = (T*)ptr_; - ptr_ += n * sizeof(T); - return r; - } - void deallocate(pointer p, size_type n) - { - if ((char*)(p + n) == ptr_) - ptr_ = (char*)p; - } - - size_type max_size() const {return N;} -}; - -template -inline -void -swap(stack_allocator& x, stack_allocator& y) {} - -#endif // STACK_ALLOCATOR_H diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h index 394d1ccd4..414733715 100644 --- a/test/support/test_allocator.h +++ b/test/support/test_allocator.h @@ -302,5 +302,78 @@ operator!=(const TaggingAllocator&, const TaggingAllocator&) { return false; } #endif +template +struct limited_alloc_handle { + std::size_t outstanding_; + void* last_alloc_; + + limited_alloc_handle() : outstanding_(0), last_alloc_(nullptr) {} + + template + T *allocate(std::size_t N) { + if (N + outstanding_ > MaxAllocs) + TEST_THROW(std::bad_alloc()); + last_alloc_ = ::operator new(N*sizeof(T)); + outstanding_ += N; + return static_cast(last_alloc_); + } + + void deallocate(void* ptr, std::size_t N) { + if (ptr == last_alloc_) { + last_alloc_ = nullptr; + assert(outstanding_ >= N); + outstanding_ -= N; + } + ::operator delete(ptr); + } +}; + +template +class limited_allocator +{ + typedef limited_alloc_handle BuffT; + std::shared_ptr handle_; +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template struct rebind { typedef limited_allocator other; }; + + limited_allocator() : handle_(new BuffT) {} + + limited_allocator(limited_allocator const& other) : handle_(other.handle_) {} + + template + explicit limited_allocator(limited_allocator const& other) + : handle_(other.handle_) {} + +private: + limited_allocator& operator=(const limited_allocator&);// = delete; + +public: + pointer allocate(size_type n) { return handle_->template allocate(n); } + void deallocate(pointer p, size_type n) { handle_->deallocate(p, n); } + size_type max_size() const {return N;} + + BuffT* getHandle() const { return handle_.get(); } +}; + +template +inline bool operator==(limited_allocator const& LHS, + limited_allocator const& RHS) { + return LHS.getHandle() == RHS.getHandle(); +} + +template +inline bool operator!=(limited_allocator const& LHS, + limited_allocator const& RHS) { + return !(LHS == RHS); +} + #endif // TEST_ALLOCATOR_H