1// Test basic new functionality.
2// RUN: %clangxx_hwasan -std=c++17 %s -o %t -fsized-deallocation
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
12void operator_new_delete(size_t size) {
13 void *alloc = operator new(size);
14 assert(alloc != nullptr);
15 assert(__sanitizer_get_allocated_size(p: alloc) == size);
16 operator delete(alloc);
17
18 alloc = operator new(size);
19 assert(alloc != nullptr);
20 assert(__sanitizer_get_allocated_size(p: alloc) == size);
21 operator delete(alloc, size);
22}
23
24void operator_new_delete_array(size_t size) {
25 void *alloc = operator new[](size);
26 assert(alloc != nullptr);
27 assert(__sanitizer_get_allocated_size(p: alloc) == size);
28 operator delete[](alloc);
29
30 alloc = operator new[](size);
31 assert(alloc != nullptr);
32 assert(__sanitizer_get_allocated_size(p: alloc) == size);
33 operator delete[](alloc, size);
34}
35
36void 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(p: 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(p: alloc) >= size);
47 operator delete(alloc, size, align);
48}
49
50void 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(p: 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(p: alloc) >= size);
61 operator delete[](alloc, size, align);
62}
63
64void 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(p: alloc) == size);
68 operator delete(alloc, tag);
69}
70
71void 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(p: alloc) == size);
75 operator delete[](alloc, tag);
76}
77
78void 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(p: alloc) >= size);
83 operator delete(alloc, align, tag);
84}
85
86void 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(p: alloc) >= size);
91 operator delete[](alloc, align, tag);
92}
93
94void 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
100void 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
106int 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(p: a1) == 1);
113 delete[] a1;
114
115 constexpr size_t kSize = 8;
116 operator_new_delete(size: kSize);
117 operator_new_delete_array(size: 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(size: kSize, ptr: buffer);
123 operator_new_delete_array(size: kSize, ptr: 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(p: 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

source code of compiler-rt/test/hwasan/TestCases/new-test.cpp