xref: /llvm-project/compiler-rt/test/hwasan/TestCases/new-test.cpp (revision c27415ff86a617bdaaf310f6888f084bdf0705ea)
1f9e0df07SNico Weber // Test basic new functionality.
2*c27415ffSFangrui Song // RUN: %clangxx_hwasan -std=c++17 %s -o %t
3f9e0df07SNico Weber // RUN: %run %t
4f9e0df07SNico Weber 
5c990d56dSVitaly Buka #include <cassert>
6c990d56dSVitaly Buka #include <cstdint>
7c990d56dSVitaly Buka #include <cstdlib>
8c990d56dSVitaly Buka #include <new>
9a908c535SNico Weber #include <sanitizer/allocator_interface.h>
10c990d56dSVitaly Buka #include <sanitizer/hwasan_interface.h>
11f9e0df07SNico Weber 
1222b76854SLeonard Chan void operator_new_delete(size_t size) {
1322b76854SLeonard Chan 	void *alloc = operator new(size);
1422b76854SLeonard Chan 	assert(alloc != nullptr);
1522b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
1622b76854SLeonard Chan 	operator delete(alloc);
1722b76854SLeonard Chan 
1822b76854SLeonard Chan 	alloc = operator new(size);
1922b76854SLeonard Chan 	assert(alloc != nullptr);
2022b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
2122b76854SLeonard Chan 	operator delete(alloc, size);
2222b76854SLeonard Chan }
2322b76854SLeonard Chan 
2422b76854SLeonard Chan void operator_new_delete_array(size_t size) {
2522b76854SLeonard Chan 	void *alloc = operator new[](size);
2622b76854SLeonard Chan 	assert(alloc != nullptr);
2722b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
2822b76854SLeonard Chan 	operator delete[](alloc);
2922b76854SLeonard Chan 
3022b76854SLeonard Chan 	alloc = operator new[](size);
3122b76854SLeonard Chan 	assert(alloc != nullptr);
3222b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
3322b76854SLeonard Chan 	operator delete[](alloc, size);
3422b76854SLeonard Chan }
3522b76854SLeonard Chan 
3622b76854SLeonard Chan void operator_new_delete(size_t size, std::align_val_t align) {
3722b76854SLeonard Chan 	void *alloc = operator new(size, align);
3822b76854SLeonard Chan 	assert(alloc != nullptr);
3922b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
4022b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
4122b76854SLeonard Chan 	operator delete(alloc, align);
4222b76854SLeonard Chan 
4322b76854SLeonard Chan 	alloc = operator new(size, align);
4422b76854SLeonard Chan 	assert(alloc != nullptr);
4522b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
4622b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
4722b76854SLeonard Chan 	operator delete(alloc, size, align);
4822b76854SLeonard Chan }
4922b76854SLeonard Chan 
5022b76854SLeonard Chan void operator_new_delete_array(size_t size, std::align_val_t align) {
5122b76854SLeonard Chan 	void *alloc = operator new[](size, align);
5222b76854SLeonard Chan 	assert(alloc != nullptr);
5322b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
5422b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
5522b76854SLeonard Chan 	operator delete[](alloc, align);
5622b76854SLeonard Chan 
5722b76854SLeonard Chan 	alloc = operator new[](size, align);
5822b76854SLeonard Chan 	assert(alloc != nullptr);
5922b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
6022b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
6122b76854SLeonard Chan 	operator delete[](alloc, size, align);
6222b76854SLeonard Chan }
6322b76854SLeonard Chan 
6422b76854SLeonard Chan void operator_new_delete(size_t size, const std::nothrow_t &tag) {
6522b76854SLeonard Chan 	void *alloc = operator new(size, tag);
6622b76854SLeonard Chan 	assert(alloc != nullptr);
6722b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
6822b76854SLeonard Chan 	operator delete(alloc, tag);
6922b76854SLeonard Chan }
7022b76854SLeonard Chan 
7122b76854SLeonard Chan void operator_new_delete_array(size_t size, const std::nothrow_t &tag) {
7222b76854SLeonard Chan 	void *alloc = operator new[](size, tag);
7322b76854SLeonard Chan 	assert(alloc != nullptr);
7422b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) == size);
7522b76854SLeonard Chan 	operator delete[](alloc, tag);
7622b76854SLeonard Chan }
7722b76854SLeonard Chan 
7822b76854SLeonard Chan void operator_new_delete(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
7922b76854SLeonard Chan 	void *alloc = operator new(size, align, tag);
8022b76854SLeonard Chan 	assert(alloc != nullptr);
8122b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
8222b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
8322b76854SLeonard Chan 	operator delete(alloc, align, tag);
8422b76854SLeonard Chan }
8522b76854SLeonard Chan 
8622b76854SLeonard Chan void operator_new_delete_array(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
8722b76854SLeonard Chan 	void *alloc = operator new[](size, align, tag);
8822b76854SLeonard Chan 	assert(alloc != nullptr);
8922b76854SLeonard Chan   assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
9022b76854SLeonard Chan 	assert(__sanitizer_get_allocated_size(alloc) >= size);
9122b76854SLeonard Chan 	operator delete[](alloc, align, tag);
9222b76854SLeonard Chan }
9322b76854SLeonard Chan 
9422b76854SLeonard Chan void operator_new_delete(size_t size, void *ptr) {
9522b76854SLeonard Chan 	void *alloc = operator new(size, ptr);
9622b76854SLeonard Chan 	assert(alloc == ptr);
9722b76854SLeonard Chan 	operator delete(alloc, ptr);
9822b76854SLeonard Chan }
9922b76854SLeonard Chan 
10022b76854SLeonard Chan void operator_new_delete_array(size_t size, void *ptr) {
10122b76854SLeonard Chan 	void *alloc = operator new[](size, ptr);
10222b76854SLeonard Chan 	assert(alloc == ptr);
10322b76854SLeonard Chan 	operator delete[](alloc, ptr);
10422b76854SLeonard Chan }
10522b76854SLeonard Chan 
106f9e0df07SNico Weber int main() {
107f9e0df07SNico Weber   __hwasan_enable_allocator_tagging();
108f9e0df07SNico Weber 
109f9e0df07SNico Weber   size_t volatile n = 0;
110f9e0df07SNico Weber   char *a1 = new char[n];
111f9e0df07SNico Weber   assert(a1 != nullptr);
11201176191SKirill Stoimenov   assert(__sanitizer_get_allocated_size(a1) == 1);
113f9e0df07SNico Weber   delete[] a1;
114c990d56dSVitaly Buka 
11522b76854SLeonard Chan 	constexpr size_t kSize = 8;
11622b76854SLeonard Chan 	operator_new_delete(kSize);
11722b76854SLeonard Chan 	operator_new_delete_array(kSize);
11822b76854SLeonard Chan 	operator_new_delete(kSize, std::nothrow);
11922b76854SLeonard Chan 	operator_new_delete_array(kSize, std::nothrow);
12022b76854SLeonard Chan 
12122b76854SLeonard Chan 	char buffer[kSize];
12222b76854SLeonard Chan 	operator_new_delete(kSize, buffer);
12322b76854SLeonard Chan 	operator_new_delete_array(kSize, buffer);
12422b76854SLeonard Chan 
1253e6cfc63SHans Wennborg #if defined(__cpp_aligned_new) &&                                              \
1263e6cfc63SHans Wennborg     (!defined(__GLIBCXX__) ||                                                  \
1273e6cfc63SHans Wennborg      (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7))
128c990d56dSVitaly Buka   // Aligned new/delete
129c990d56dSVitaly Buka   constexpr auto kAlign = std::align_val_t{8};
130c990d56dSVitaly Buka   void *a2 = ::operator new(4, kAlign);
131c990d56dSVitaly Buka   assert(a2 != nullptr);
132c990d56dSVitaly Buka   assert(reinterpret_cast<uintptr_t>(a2) % static_cast<uintptr_t>(kAlign) == 0);
133c990d56dSVitaly Buka   assert(__sanitizer_get_allocated_size(a2) >= 4);
134c990d56dSVitaly Buka   ::operator delete(a2, kAlign);
13522b76854SLeonard Chan 
13622b76854SLeonard Chan 	operator_new_delete(kSize, std::align_val_t{kSize});
13722b76854SLeonard Chan 	operator_new_delete_array(kSize, std::align_val_t{kSize});
13822b76854SLeonard Chan 	operator_new_delete(kSize, std::align_val_t{kSize * 2});
13922b76854SLeonard Chan 	operator_new_delete_array(kSize, std::align_val_t{kSize * 2});
14022b76854SLeonard Chan 	operator_new_delete(kSize, std::align_val_t{kSize}, std::nothrow);
14122b76854SLeonard Chan 	operator_new_delete_array(kSize, std::align_val_t{kSize}, std::nothrow);
14222b76854SLeonard Chan 	operator_new_delete(kSize, std::align_val_t{kSize * 2}, std::nothrow);
14322b76854SLeonard Chan 	operator_new_delete_array(kSize, std::align_val_t{kSize * 2}, std::nothrow);
144c990d56dSVitaly Buka #endif
145f9e0df07SNico Weber }
146