1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03
10
11 // <vector>
12
13 // Test based on: https://bugs.chromium.org/p/chromium/issues/detail?id=1419798#c5
14 // Some allocators during deallocation may not call destructors and just reuse memory.
15 // In those situations, one may want to deactivate annotations for a specific allocator.
16 // It's possible with __asan_annotate_container_with_allocator template class.
17 // This test confirms that those allocators work after turning off annotations.
18
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <vector>
22 #include <new>
23
24 struct reuse_allocator {
25 static size_t const N = 100;
reuse_allocatorreuse_allocator26 reuse_allocator() {
27 for (size_t i = 0; i < N; ++i)
28 __buffers[i] = malloc(8*1024);
29 }
~reuse_allocatorreuse_allocator30 ~reuse_allocator() {
31 for (size_t i = 0; i < N; ++i)
32 free(__buffers[i]);
33 }
allocreuse_allocator34 void* alloc() {
35 assert(__next_id < N);
36 return __buffers[__next_id++];
37 }
resetreuse_allocator38 void reset() { __next_id = 0; }
39 void* __buffers[N];
40 size_t __next_id = 0;
41 } reuse_buffers;
42
43 template <typename T>
44 struct user_allocator {
45 using value_type = T;
46 user_allocator() = default;
47 template <class U>
user_allocatoruser_allocator48 user_allocator(user_allocator<U>) {}
operator ==(user_allocator,user_allocator)49 friend bool operator==(user_allocator, user_allocator) {return true;}
operator !=(user_allocator x,user_allocator y)50 friend bool operator!=(user_allocator x, user_allocator y) {return !(x == y);}
51
allocateuser_allocator52 T* allocate(size_t) { return (T*)reuse_buffers.alloc(); }
deallocateuser_allocator53 void deallocate(T*, size_t) noexcept {}
54 };
55
56 #ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
57 template <class T>
58 struct std::__asan_annotate_container_with_allocator<user_allocator<T>> : false_type {};
59 #endif
60
main(int,char **)61 int main(int, char**) {
62 using V = std::vector<int, user_allocator<int>>;
63
64 {
65 V* v = new (reuse_buffers.alloc()) V();
66 for (int i = 0; i < 100; i++)
67 v->push_back(i);
68 }
69 reuse_buffers.reset();
70 {
71 V v;
72 for (int i = 0; i < 1000; i++)
73 v.push_back(i);
74 }
75
76 return 0;
77 }
78