[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