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