1 | // RUN: %clangxx -std=c++1z -faligned-allocation -O0 %s -o %t && %run %t |
2 | // RUN: %clangxx -std=c++1z -faligned-allocation -fsized-deallocation -O0 %s -o %t && %run %t |
3 | |
4 | // ubsan does not intercept new/delete. |
5 | // UNSUPPORTED: ubsan |
6 | |
7 | // Check that all new/delete variants are defined and work with supported |
8 | // sanitizers. Sanitizer-specific failure modes tests are supposed to go to |
9 | // the particular sanitizer's test suites. |
10 | |
11 | #include <cstddef> |
12 | |
13 | // Define all new/delete to do not depend on the version provided by the |
14 | // platform. The implementation is provided by the sanitizer anyway. |
15 | |
16 | namespace std { |
17 | struct nothrow_t {}; |
18 | static const nothrow_t nothrow; |
19 | enum class align_val_t : size_t {}; |
20 | } // namespace std |
21 | |
22 | void *operator new(size_t); |
23 | void *operator new[](size_t); |
24 | void *operator new(size_t, std::nothrow_t const&); |
25 | void *operator new[](size_t, std::nothrow_t const&); |
26 | void *operator new(size_t, std::align_val_t); |
27 | void *operator new[](size_t, std::align_val_t); |
28 | void *operator new(size_t, std::align_val_t, std::nothrow_t const&); |
29 | void *operator new[](size_t, std::align_val_t, std::nothrow_t const&); |
30 | |
31 | void operator delete(void*) throw(); |
32 | void operator delete[](void*) throw(); |
33 | void operator delete(void*, std::nothrow_t const&); |
34 | void operator delete[](void*, std::nothrow_t const&); |
35 | void operator delete(void*, size_t) throw(); |
36 | void operator delete[](void*, size_t) throw(); |
37 | void operator delete(void*, std::align_val_t) throw(); |
38 | void operator delete[](void*, std::align_val_t) throw(); |
39 | void operator delete(void*, std::align_val_t, std::nothrow_t const&); |
40 | void operator delete[](void*, std::align_val_t, std::nothrow_t const&); |
41 | void operator delete(void*, size_t, std::align_val_t) throw(); |
42 | void operator delete[](void*, size_t, std::align_val_t) throw(); |
43 | |
44 | |
45 | template<typename T> |
46 | inline T* break_optimization(T *arg) { |
47 | __asm__ __volatile__("" : : "r" (arg) : "memory" ); |
48 | return arg; |
49 | } |
50 | |
51 | |
52 | struct S12 { int a, b, c; }; |
53 | struct alignas(128) S12_128 { int a, b, c; }; |
54 | struct alignas(256) S12_256 { int a, b, c; }; |
55 | struct alignas(512) S1024_512 { char a[1024]; }; |
56 | struct alignas(1024) S1024_1024 { char a[1024]; }; |
57 | |
58 | |
59 | int main(int argc, char **argv) { |
60 | delete break_optimization(arg: new S12); |
61 | operator delete(break_optimization(arg: new S12), std::nothrow); |
62 | delete [] break_optimization(arg: new S12[100]); |
63 | operator delete[](break_optimization(arg: new S12[100]), std::nothrow); |
64 | |
65 | delete break_optimization(arg: new S12_128); |
66 | operator delete(break_optimization(arg: new S12_128), |
67 | std::align_val_t(alignof(S12_128))); |
68 | operator delete(break_optimization(arg: new S12_128), |
69 | std::align_val_t(alignof(S12_128)), std::nothrow); |
70 | operator delete(break_optimization(arg: new S12_128), sizeof(S12_128), |
71 | std::align_val_t(alignof(S12_128))); |
72 | |
73 | delete [] break_optimization(arg: new S12_128[100]); |
74 | operator delete[](break_optimization(arg: new S12_128[100]), |
75 | std::align_val_t(alignof(S12_128))); |
76 | operator delete[](break_optimization(arg: new S12_128[100]), |
77 | std::align_val_t(alignof(S12_128)), std::nothrow); |
78 | operator delete[](break_optimization(arg: new S12_128[100]), sizeof(S12_128[100]), |
79 | std::align_val_t(alignof(S12_128))); |
80 | } |
81 | |