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