xref: /llvm-project/libcxx/test/libcxx/containers/sequences/vector/asan_turning_off.pass.cpp (revision c08d4ad25cf3f335e9b2e7b1b149eb1b486868f1)
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