Index: include/new =================================================================== --- include/new +++ include/new @@ -139,9 +139,11 @@ ; _LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_NEW_DELETE_VIS void operator delete(void* __p) _NOEXCEPT; +_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; +#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 _LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; -_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; _LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz, const std::nothrow_t&) _NOEXCEPT; +#endif _LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz) #if !__has_feature(cxx_noexcept) @@ -150,9 +152,11 @@ ; _LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p) _NOEXCEPT; +_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; +#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 _LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; -_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; _LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz, const std::nothrow_t&) _NOEXCEPT; +#endif inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;} inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;} Index: src/new.cpp =================================================================== --- src/new.cpp +++ src/new.cpp @@ -126,24 +126,26 @@ _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete(void* ptr, size_t) _NOEXCEPT +operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT { ::operator delete(ptr); } +#if _LIBCPP_STD_VER >= 14 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT +operator delete(void* ptr, size_t) _NOEXCEPT { ::operator delete(ptr); } _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete(void* ptr, size_t, const std::nothrow_t&) _NOEXCEPT +operator delete(void* ptr, size_t, const std::nothrow_t& nt) _NOEXCEPT { - ::operator delete(ptr); + ::operator delete(ptr, nt); } +#endif // _LIBCPP_STD_VER >= 14 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void @@ -154,24 +156,26 @@ _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete[] (void* ptr, size_t) _NOEXCEPT +operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT { ::operator delete[](ptr); } +#if _LIBCPP_STD_VER >= 14 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT +operator delete[] (void* ptr, size_t) _NOEXCEPT { ::operator delete[](ptr); } _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS void -operator delete[] (void* ptr, size_t, const std::nothrow_t&) _NOEXCEPT +operator delete[] (void* ptr, size_t, const std::nothrow_t&, nt) _NOEXCEPT { - ::operator delete[](ptr); + ::operator delete[](ptr, nt); } +#endif // _LIBCPP_STD_VER >= 14 #endif // !__GLIBCXX__ Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test sized operator delete[] by replacing unsized operator delete[] + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int delete_called = 0; +int delete_nothrow_called = 0; + +void operator delete[](void* p) throw() +{ + ++delete_called; + delete_nothrow_called; + std::free(p); +} + +void operator delete[](void* p, const std::nothrow_t&) throw() +{ + ++delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A[3]; + assert(ap); + assert(A_constructed == 3); + assert(!delete_called); + assert(!delete_nothrow_called); + delete [] ap; + assert(!A_constructed); + assert(delete_called == 1); + assert(!delete_nothrow_called); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test nothrow sized operator delete[] by replacing +// nothrow unsized operator delete[]. + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int delete_called = 0; +int delete_nothrow_called = 0; + +void operator delete[](void* p) throw() +{ + ++delete_called; + std::free(p); +} + +void operator delete[](void* p, const std::nothrow_t&) throw() +{ + ++delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A(std::nothrow) [3]; + assert(ap); + assert(A_constructed == 3); + assert(!delete_called); + assert(!delete_nothrow_called); + delete [] ap; + assert(!A_constructed); + assert(!delete_called); + assert(delete_nothrow_called == 1); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test nothrow sized operator delete[] replacement + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int sized_delete_called = 0; +int sized_delete_nothrow_called = 0; + +void operator delete[](void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete[](void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete[](void* p, std::size_t) throw() +{ + ++size_delete_called; + std::free(p); +} + +void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw() +{ + ++size_delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A(std::nothrow) [3]; + assert(ap); + assert(A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(!sized_delete_nothrow_called); + delete [] ap; + assert(!A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(sized_delete_nothrow_called == 1); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test sized operator delete[] replacement + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int sized_delete_called = 0; +int sized_delete_nothrow_called = 0; + +void operator delete[](void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete[](void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete[](void* p, std::size_t) throw() +{ + ++size_delete_called; + std::free(p); +} + +void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw() +{ + ++size_delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A[3]; + assert(ap); + assert(A_constructed == 3); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(!sized_delete_nothrow_called); + delete [] ap; + assert(!A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(sized_delete_called == 1); + assert(!sized_delete_nothrow_called); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test sized operator delete by replacing unsized operator delete + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int delete_called = 0; +int delete_nothrow_called = 0; + +void operator delete(void* p) throw() +{ + ++delete_called; + delete_nothrow_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A; + assert(ap); + assert(A_constructed); + assert(!delete_called); + assert(!delete_nothrow_called); + delete ap; + assert(!A_constructed); + assert(delete_called == 1); + assert(!delete_nothrow_called); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test nothrow sized operator delete by replacing +// nothrow unsized operator delete. + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int delete_called = 0; +int delete_nothrow_called = 0; + +void operator delete(void* p) throw() +{ + ++delete_called; + delete_nothrow_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A(std::nothrow); + assert(ap); + assert(A_constructed); + assert(!delete_called); + assert(!delete_nothrow_called); + delete ap; + assert(!A_constructed); + assert(!delete_called); + assert(delete_nothrow_called == 1); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test nothrow sized operator delete replacement + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int sized_delete_called = 0; +int sized_delete_nothrow_called = 0; + +void operator delete(void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete(void* p, std::size_t) throw() +{ + ++size_delete_called; + std::free(p); +} + +void operator delete(void* p, std::size_t, const std::nothrow_t&) throw() +{ + ++size_delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A(std::nothrow); + assert(ap); + assert(A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(!sized_delete_nothrow_called); + delete ap; + assert(!A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(sized_delete_nothrow_called == 1); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14 Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp =================================================================== --- test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp +++ test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test sized operator delete replacement + +// UNSUPPORTED: asan, msan + +#include +#include +#include +#include +#include + +#if _LIBCPP_STD_VER >= 14 + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int sized_delete_called = 0; +int sized_delete_nothrow_called = 0; + +void operator delete(void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete(void* p, std::size_t) throw() +{ + ++size_delete_called; + std::free(p); +} + +void operator delete(void* p, std::size_t, const std::nothrow_t&) throw() +{ + ++size_delete_nothrow_called; + std::free(p); +} + +bool A_constructed = false; + +struct A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +int main() +{ + A* ap = new A; + assert(ap); + assert(A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(!sized_delete_called); + assert(!sized_delete_nothrow_called); + delete ap; + assert(!A_constructed); + assert(!unsized_delete_called); + assert(!unsized_delete_nothrow_called); + assert(sized_delete_called == 1); + assert(!sized_delete_nothrow_called); +} + +#else + +int main () {} + +#endif // _LIBCPP_STD_VER >= 14