Kostya Kortchinsky | 76969ea | 2018-06-12 14:42:40 +0000 | [diff] [blame] | 1 | // RUN: %clangxx_scudo -std=c++1z -faligned-allocation %s -o %t |
Kostya Kortchinsky | 4adf2450 | 2018-06-15 16:45:19 +0000 | [diff] [blame^] | 2 | // RUN: %run %t valid 2>&1 |
| 3 | // RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1 |
| 4 | // RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t invalid 2>&1 | FileCheck %s |
Kostya Kortchinsky | 76969ea | 2018-06-12 14:42:40 +0000 | [diff] [blame] | 5 | |
| 6 | // Tests that the C++17 aligned new/delete operators are working as expected. |
| 7 | // Currently we do not check the consistency of the alignment on deallocation, |
| 8 | // so this just tests that the APIs work. |
| 9 | |
| 10 | #include <assert.h> |
| 11 | #include <stdio.h> |
| 12 | #include <stdint.h> |
| 13 | #include <string.h> |
| 14 | |
| 15 | // Define all new/delete to not depend on the version provided by the platform. |
| 16 | |
| 17 | namespace std { |
| 18 | struct nothrow_t {}; |
| 19 | static const nothrow_t nothrow; |
| 20 | enum class align_val_t : size_t {}; |
| 21 | } // namespace std |
| 22 | |
| 23 | void *operator new(size_t); |
| 24 | void *operator new[](size_t); |
| 25 | void *operator new(size_t, std::nothrow_t const&); |
| 26 | void *operator new[](size_t, std::nothrow_t const&); |
| 27 | void *operator new(size_t, std::align_val_t); |
| 28 | void *operator new[](size_t, std::align_val_t); |
| 29 | void *operator new(size_t, std::align_val_t, std::nothrow_t const&); |
| 30 | void *operator new[](size_t, std::align_val_t, std::nothrow_t const&); |
| 31 | |
| 32 | void operator delete(void*) throw(); |
| 33 | void operator delete[](void*) throw(); |
| 34 | void operator delete(void*, std::nothrow_t const&); |
| 35 | void operator delete[](void*, std::nothrow_t const&); |
| 36 | void operator delete(void*, size_t) throw(); |
| 37 | void operator delete[](void*, size_t) throw(); |
| 38 | void operator delete(void*, std::align_val_t) throw(); |
| 39 | void operator delete[](void*, std::align_val_t) throw(); |
| 40 | void operator delete(void*, std::align_val_t, std::nothrow_t const&); |
| 41 | void operator delete[](void*, std::align_val_t, std::nothrow_t const&); |
| 42 | void operator delete(void*, size_t, std::align_val_t) throw(); |
| 43 | void operator delete[](void*, size_t, std::align_val_t) throw(); |
| 44 | |
| 45 | template<typename T> |
| 46 | inline T* break_optimization(T *arg) { |
| 47 | __asm__ __volatile__("" : : "r" (arg) : "memory"); |
| 48 | return arg; |
| 49 | } |
| 50 | |
| 51 | struct S12 { int a, b, c; }; |
| 52 | struct alignas(128) S12_128 { int a, b, c; }; |
| 53 | struct alignas(256) S12_256 { int a, b, c; }; |
| 54 | struct alignas(512) S1024_512 { char a[1024]; }; |
| 55 | struct alignas(1024) S1024_1024 { char a[1024]; }; |
| 56 | |
| 57 | int main(int argc, char **argv) { |
| 58 | assert(argc == 2); |
| 59 | |
| 60 | if (!strcmp(argv[1], "valid")) { |
| 61 | // Standard use case. |
| 62 | delete break_optimization(new S12); |
| 63 | delete break_optimization(new S12_128); |
| 64 | delete[] break_optimization(new S12_128[4]); |
| 65 | delete break_optimization(new S12_256); |
| 66 | delete break_optimization(new S1024_512); |
| 67 | delete[] break_optimization(new S1024_512[4]); |
| 68 | delete break_optimization(new S1024_1024); |
| 69 | |
| 70 | // Call directly the aligned versions of the operators. |
| 71 | const size_t alignment = 1U << 8; |
| 72 | void *p = operator new(1, static_cast<std::align_val_t>(alignment)); |
| 73 | assert((reinterpret_cast<uintptr_t>(p) & (alignment - 1)) == 0); |
| 74 | operator delete(p, static_cast<std::align_val_t>(alignment)); |
| 75 | } |
| 76 | if (!strcmp(argv[1], "invalid")) { |
| 77 | // Alignment must be a power of 2. |
| 78 | const size_t alignment = (1U << 8) - 1; |
| 79 | void *p = operator new(1, static_cast<std::align_val_t>(alignment), |
| 80 | std::nothrow); |
Kostya Kortchinsky | 4adf2450 | 2018-06-15 16:45:19 +0000 | [diff] [blame^] | 81 | // CHECK: Scudo ERROR: invalid allocation alignment |
Kostya Kortchinsky | 76969ea | 2018-06-12 14:42:40 +0000 | [diff] [blame] | 82 | assert(!p); |
| 83 | } |
| 84 | |
| 85 | return 0; |
| 86 | } |