[libcxx] r229968 - More on adding sized deallocation functions in libc++: Continuing from r229281, this adds version guards and test cases.
Larisse Voufo
lvoufo at google.com
Thu Feb 19 22:13:05 PST 2015
Author: lvoufo
Date: Fri Feb 20 00:13:05 2015
New Revision: 229968
URL: http://llvm.org/viewvc/llvm-project?rev=229968&view=rev
Log:
More on adding sized deallocation functions in libc++: Continuing from r229281, this adds version guards and test cases.
Added:
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp
libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp
Modified:
libcxx/trunk/include/new
libcxx/trunk/src/new.cpp
Modified: libcxx/trunk/include/new
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/new?rev=229968&r1=229967&r2=229968&view=diff
==============================================================================
--- libcxx/trunk/include/new (original)
+++ libcxx/trunk/include/new Fri Feb 20 00:13:05 2015
@@ -139,9 +139,11 @@ _LIBCPP_NEW_DELETE_VIS void* operator ne
;
_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, std::size_t __sz) _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, 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 ne
;
_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, std::size_t __sz) _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, 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;}
Modified: libcxx/trunk/src/new.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/new.cpp?rev=229968&r1=229967&r2=229968&view=diff
==============================================================================
--- libcxx/trunk/src/new.cpp (original)
+++ libcxx/trunk/src/new.cpp Fri Feb 20 00:13:05 2015
@@ -126,23 +126,23 @@ operator delete(void* ptr) _NOEXCEPT
_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);
}
_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);
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
@@ -154,23 +154,23 @@ operator delete[] (void* ptr) _NOEXCEPT
_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);
}
_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 // !__GLIBCXX__
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct A
+{
+ A() {++A_constructed;}
+ ~A() {--A_constructed;}
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new [] (std::numeric_limits<std::size_t>::max());
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ A* ap = new A[3];
+ assert(ap);
+ assert(A_constructed == 3);
+ assert(!delete_called);
+ assert(!delete_nothrow_called);
+ delete [] ap;
+ assert(A_constructed == 0);
+ assert(delete_called == 1);
+ assert(!delete_nothrow_called);
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp Fri Feb 20 00:13:05 2015
@@ -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[] by replacing
+// nothrow unsized operator delete[].
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+struct BadA : public A {
+ BadA() { throw std::bad_alloc(); }
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ try
+ {
+ A* ap = new(std::nothrow) BadA [3];
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(!A_constructed);
+ assert(!delete_called);
+ assert(delete_nothrow_called == 1);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw()
+{
+ ++sized_delete_nothrow_called;
+ std::free(p);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+struct BadA : public A {
+ BadA() { throw std::bad_alloc(); }
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ try
+ {
+ A* ap = new(std::nothrow) BadA [3];
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(!A_constructed);
+#if _LIBCPP_STD_VER >= 14
+ // FIXME: Do we need a version of [Expr.Delete]#10 for nothrow
+ // deallocation functions (selecting sized ones whenever available)?
+ // It is not required by the standard. If it were, the following would
+ // be the expected behaviour (instead of the current one):
+ // assert(!unsized_delete_nothrow_called);
+ // assert(sized_delete_nothrow_called == 1);
+ assert(unsized_delete_nothrow_called == 1);
+ assert(!sized_delete_nothrow_called);
+#else // if _LIBCPP_STD_VER < 14
+ assert(unsized_delete_nothrow_called == 1);
+ assert(!sized_delete_nothrow_called);
+#endif
+ assert(!unsized_delete_called);
+ assert(!sized_delete_called);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw()
+{
+ ++sized_delete_nothrow_called;
+ std::free(p);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct A
+{
+ A() {++A_constructed;}
+ ~A() {--A_constructed;}
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new [] (std::numeric_limits<std::size_t>::max());
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ 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 == 0);
+#if _LIBCPP_STD_VER >= 14
+ assert(!unsized_delete_called);
+ assert(sized_delete_called == 1);
+#else // if _LIBCPP_STD_VER < 14
+ assert(unsized_delete_called == 1);
+ assert(!sized_delete_called);
+#endif
+ assert(!unsized_delete_nothrow_called);
+ assert(!sized_delete_nothrow_called);
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new (std::numeric_limits<std::size_t>::max());
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ 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);
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp Fri Feb 20 00:13:05 2015
@@ -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 by replacing
+// nothrow unsized operator delete.
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+struct BadA : public A {
+ BadA() { throw std::bad_alloc(); }
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* volatile vp = operator new (std::numeric_limits<std::size_t>::max(), std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ try
+ {
+ A* ap = new(std::nothrow) BadA;
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(!A_constructed);
+ assert(!delete_called);
+ assert(delete_nothrow_called == 1);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::size_t, const std::nothrow_t&) throw()
+{
+ ++sized_delete_nothrow_called;
+ std::free(p);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+struct BadA : public A {
+ BadA() { throw std::bad_alloc(); }
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void*volatile vp = operator new (std::numeric_limits<std::size_t>::max(), std::nothrow);
+ assert(new_handler_called == 1);
+ assert(vp == 0);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ try
+ {
+ A* ap = new(std::nothrow) BadA;
+ assert(false);
+ }
+ catch (...)
+ {
+ assert(!A_constructed);
+#if _LIBCPP_STD_VER >= 14
+ // FIXME: Do we need a version of [Expr.Delete]#10 for nothrow
+ // deallocation functions (selecting sized ones whenever available)?
+ // It is not required by the standard. If it were, the following would
+ // be the expected behaviour (instead of the current one):
+ // assert(!unsized_delete_nothrow_called);
+ // assert(sized_delete_nothrow_called == 1);
+ assert(unsized_delete_nothrow_called == 1);
+ assert(!sized_delete_nothrow_called);
+#else // if _LIBCPP_STD_VER < 14
+ assert(unsized_delete_nothrow_called == 1);
+ assert(!sized_delete_nothrow_called);
+#endif
+ assert(!unsized_delete_called);
+ assert(!sized_delete_called);
+ }
+}
Added: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp?rev=229968&view=auto
==============================================================================
--- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp (added)
+++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp Fri Feb 20 00:13:05 2015
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: asan, msan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+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()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::size_t, const std::nothrow_t&) throw()
+{
+ ++sized_delete_nothrow_called;
+ std::free(p);
+}
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+ ++new_handler_called;
+ std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct A
+{
+ A() {A_constructed = true;}
+ ~A() {A_constructed = false;}
+};
+
+int main()
+{
+ std::set_new_handler(new_handler);
+ try
+ {
+ void* vp = operator new (std::numeric_limits<std::size_t>::max());
+ assert(false);
+ }
+ catch (std::bad_alloc&)
+ {
+ assert(new_handler_called == 1);
+ }
+ catch (...)
+ {
+ assert(false);
+ }
+ 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);
+#if _LIBCPP_STD_VER >= 14
+ assert(!unsized_delete_called);
+ assert(sized_delete_called == 1);
+#else // if _LIBCPP_STD_VER < 14
+ assert(unsized_delete_called == 1);
+ assert(!sized_delete_called);
+#endif
+ assert(!unsized_delete_nothrow_called);
+ assert(!sized_delete_nothrow_called);
+}
More information about the cfe-commits
mailing list