1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// test aligned operator delete replacement.
11
12// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
13
14// Older Clang versions do not support this
15// XFAIL: clang-3, apple-clang
16
17// None of the current GCC compilers support this.
18// XFAIL: gcc
19
20#include <new>
21#include <cstddef>
22#include <cstdlib>
23#include <cassert>
24
25#include "test_macros.h"
26
27constexpr auto OverAligned = alignof(std::max_align_t) * 2;
28
29int unsized_delete_called = 0;
30int unsized_delete_nothrow_called = 0;
31int aligned_delete_called = 0;
32
33void reset() {
34    unsized_delete_called = 0;
35    unsized_delete_nothrow_called = 0;
36    aligned_delete_called = 0;
37}
38
39void operator delete(void* p) TEST_NOEXCEPT
40{
41    ++unsized_delete_called;
42    std::free(p);
43}
44
45void operator delete(void* p, const std::nothrow_t&) TEST_NOEXCEPT
46{
47    ++unsized_delete_nothrow_called;
48    std::free(p);
49}
50
51void operator delete [] (void* p, std::align_val_t) TEST_NOEXCEPT
52{
53    ++aligned_delete_called;
54    std::free(p);
55}
56
57struct alignas(OverAligned) A {};
58struct alignas(std::max_align_t) B {};
59
60B* volatile b; // Escape the memory
61A* volatile a;
62
63int main()
64{
65    reset();
66    {
67        b = new B[2];
68        assert(0 == unsized_delete_called);
69        assert(0 == unsized_delete_nothrow_called);
70        assert(0 == aligned_delete_called);
71
72        delete [] b;
73        assert(1 == unsized_delete_called);
74        assert(0 == unsized_delete_nothrow_called);
75        assert(0 == aligned_delete_called);
76    }
77    reset();
78    {
79        a = new A[2];
80        assert(0 == unsized_delete_called);
81        assert(0 == unsized_delete_nothrow_called);
82        assert(0 == aligned_delete_called);
83
84        delete [] a;
85        assert(0 == unsized_delete_called);
86        assert(0 == unsized_delete_nothrow_called);
87        assert(1 == aligned_delete_called);
88    }
89}
90