xref: /llvm-project/compiler-rt/test/hwasan/TestCases/new-test.cpp (revision c27415ff86a617bdaaf310f6888f084bdf0705ea)
1 // Test basic new functionality.
2 // RUN: %clangxx_hwasan -std=c++17 %s -o %t
3 // RUN: %run %t
4 
5 #include <cassert>
6 #include <cstdint>
7 #include <cstdlib>
8 #include <new>
9 #include <sanitizer/allocator_interface.h>
10 #include <sanitizer/hwasan_interface.h>
11 
12 void operator_new_delete(size_t size) {
13 	void *alloc = operator new(size);
14 	assert(alloc != nullptr);
15 	assert(__sanitizer_get_allocated_size(alloc) == size);
16 	operator delete(alloc);
17 
18 	alloc = operator new(size);
19 	assert(alloc != nullptr);
20 	assert(__sanitizer_get_allocated_size(alloc) == size);
21 	operator delete(alloc, size);
22 }
23 
24 void operator_new_delete_array(size_t size) {
25 	void *alloc = operator new[](size);
26 	assert(alloc != nullptr);
27 	assert(__sanitizer_get_allocated_size(alloc) == size);
28 	operator delete[](alloc);
29 
30 	alloc = operator new[](size);
31 	assert(alloc != nullptr);
32 	assert(__sanitizer_get_allocated_size(alloc) == size);
33 	operator delete[](alloc, size);
34 }
35 
36 void operator_new_delete(size_t size, std::align_val_t align) {
37 	void *alloc = operator new(size, align);
38 	assert(alloc != nullptr);
39   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
40 	assert(__sanitizer_get_allocated_size(alloc) >= size);
41 	operator delete(alloc, align);
42 
43 	alloc = operator new(size, align);
44 	assert(alloc != nullptr);
45   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
46 	assert(__sanitizer_get_allocated_size(alloc) >= size);
47 	operator delete(alloc, size, align);
48 }
49 
50 void operator_new_delete_array(size_t size, std::align_val_t align) {
51 	void *alloc = operator new[](size, align);
52 	assert(alloc != nullptr);
53   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
54 	assert(__sanitizer_get_allocated_size(alloc) >= size);
55 	operator delete[](alloc, align);
56 
57 	alloc = operator new[](size, align);
58 	assert(alloc != nullptr);
59   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
60 	assert(__sanitizer_get_allocated_size(alloc) >= size);
61 	operator delete[](alloc, size, align);
62 }
63 
64 void operator_new_delete(size_t size, const std::nothrow_t &tag) {
65 	void *alloc = operator new(size, tag);
66 	assert(alloc != nullptr);
67 	assert(__sanitizer_get_allocated_size(alloc) == size);
68 	operator delete(alloc, tag);
69 }
70 
71 void operator_new_delete_array(size_t size, const std::nothrow_t &tag) {
72 	void *alloc = operator new[](size, tag);
73 	assert(alloc != nullptr);
74 	assert(__sanitizer_get_allocated_size(alloc) == size);
75 	operator delete[](alloc, tag);
76 }
77 
78 void operator_new_delete(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
79 	void *alloc = operator new(size, align, tag);
80 	assert(alloc != nullptr);
81   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
82 	assert(__sanitizer_get_allocated_size(alloc) >= size);
83 	operator delete(alloc, align, tag);
84 }
85 
86 void operator_new_delete_array(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
87 	void *alloc = operator new[](size, align, tag);
88 	assert(alloc != nullptr);
89   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
90 	assert(__sanitizer_get_allocated_size(alloc) >= size);
91 	operator delete[](alloc, align, tag);
92 }
93 
94 void operator_new_delete(size_t size, void *ptr) {
95 	void *alloc = operator new(size, ptr);
96 	assert(alloc == ptr);
97 	operator delete(alloc, ptr);
98 }
99 
100 void operator_new_delete_array(size_t size, void *ptr) {
101 	void *alloc = operator new[](size, ptr);
102 	assert(alloc == ptr);
103 	operator delete[](alloc, ptr);
104 }
105 
106 int main() {
107   __hwasan_enable_allocator_tagging();
108 
109   size_t volatile n = 0;
110   char *a1 = new char[n];
111   assert(a1 != nullptr);
112   assert(__sanitizer_get_allocated_size(a1) == 1);
113   delete[] a1;
114 
115 	constexpr size_t kSize = 8;
116 	operator_new_delete(kSize);
117 	operator_new_delete_array(kSize);
118 	operator_new_delete(kSize, std::nothrow);
119 	operator_new_delete_array(kSize, std::nothrow);
120 
121 	char buffer[kSize];
122 	operator_new_delete(kSize, buffer);
123 	operator_new_delete_array(kSize, buffer);
124 
125 #if defined(__cpp_aligned_new) &&                                              \
126     (!defined(__GLIBCXX__) ||                                                  \
127      (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7))
128   // Aligned new/delete
129   constexpr auto kAlign = std::align_val_t{8};
130   void *a2 = ::operator new(4, kAlign);
131   assert(a2 != nullptr);
132   assert(reinterpret_cast<uintptr_t>(a2) % static_cast<uintptr_t>(kAlign) == 0);
133   assert(__sanitizer_get_allocated_size(a2) >= 4);
134   ::operator delete(a2, kAlign);
135 
136 	operator_new_delete(kSize, std::align_val_t{kSize});
137 	operator_new_delete_array(kSize, std::align_val_t{kSize});
138 	operator_new_delete(kSize, std::align_val_t{kSize * 2});
139 	operator_new_delete_array(kSize, std::align_val_t{kSize * 2});
140 	operator_new_delete(kSize, std::align_val_t{kSize}, std::nothrow);
141 	operator_new_delete_array(kSize, std::align_val_t{kSize}, std::nothrow);
142 	operator_new_delete(kSize, std::align_val_t{kSize * 2}, std::nothrow);
143 	operator_new_delete_array(kSize, std::align_val_t{kSize * 2}, std::nothrow);
144 #endif
145 }
146