1f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//===----------------------------------------------------------------------===//
2f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//
3f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//                     The LLVM Compiler Infrastructure
4f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//
5f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
6f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// Source Licenses. See LICENSE.TXT for details.
7f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//
8f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//===----------------------------------------------------------------------===//
9f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
10f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// test sized operator delete[] replacement.
11f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
12f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// Note that sized delete operator definitions below are simply ignored
13f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// when sized deallocation is not supported, e.g., prior to C++14.
14f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
15f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// UNSUPPORTED: c++14, c++1z
16f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// UNSUPPORTED: sanitizer-new-delete
17f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
18f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier#include <new>
19f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier#include <cstddef>
20f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier#include <cstdlib>
21f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier#include <cassert>
22f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
23f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselierint unsized_delete_called = 0;
24f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselierint unsized_delete_nothrow_called = 0;
25f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselierint sized_delete_called = 0;
26f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
27f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiseliervoid operator delete[](void* p) throw()
28f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier{
29f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    ++unsized_delete_called;
30f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    std::free(p);
31f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier}
32f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
33f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiseliervoid operator delete[](void* p, const std::nothrow_t&) throw()
34f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier{
35f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    ++unsized_delete_nothrow_called;
36f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    std::free(p);
37f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier}
38f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
39f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiseliervoid operator delete[](void* p, std::size_t) throw()
40f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier{
41f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    ++sized_delete_called;
42f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    std::free(p);
43f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier}
44f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
45f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// NOTE: Use a class with a non-trivial destructor as the test type in order
46f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// to ensure the correct overload is called.
47f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// C++14 5.3.5 [expr.delete]p10
48f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// - If the type is complete and if, for the second alternative (delete array)
49f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//   only, the operand is a pointer to a class type with a non-trivial
50f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//   destructor or a (possibly multi-dimensional) array thereof, the function
51f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//   with two parameters is selected.
52f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier// - Otherwise, it is unspecified which of the two deallocation functions is
53f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier//   selected.
54f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselierstruct A { ~A() {} };
55f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
56f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselierint main()
57f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier{
58f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
59f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    A* x = new A[3];
60f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(0 == unsized_delete_called);
61f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(0 == unsized_delete_nothrow_called);
62f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(0 == sized_delete_called);
63f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier
64f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    delete [] x;
65f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(1 == unsized_delete_called);
66f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(0 == sized_delete_called);
67f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier    assert(0 == unsized_delete_nothrow_called);
68f4c97290fcf1e09dcc6ff81c2d8b436622a662deEric Fiselier}
69