[libcxx] r224741 - [libcxx] Consolidate new/delete replacement in tests and disable it when using sanitizers.

Eric Fiselier eric at efcs.ca
Mon Dec 22 14:38:59 PST 2014


Author: ericwf
Date: Mon Dec 22 16:38:59 2014
New Revision: 224741

URL: http://llvm.org/viewvc/llvm-project?rev=224741&view=rev
Log:
[libcxx] Consolidate new/delete replacement in tests and disable it when using sanitizers.

Summary:
MSAN and ASAN also replace new/delete which leads to a link error in these tests. Currently they are unsupported but I think it would be useful if these tests could run with sanitizers.

This patch creates a support header that consolidates the new/delete replacement functionality and checking.
When we are using sanitizers new and delete are no longer replaced and the checks always return true.

Reviewers: mclow.lists, danalbert, jroelofs, EricWF

Reviewed By: EricWF

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D6562

Added:
    libcxx/trunk/test/support/count_new.hpp
Modified:
    libcxx/trunk/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
    libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp
    libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp
    libcxx/trunk/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
    libcxx/trunk/test/std/localization/locales/locale/locale.cons/default.pass.cpp
    libcxx/trunk/test/std/localization/locales/locale/locale.members/combine.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
    libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
    libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
    libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp

Modified: libcxx/trunk/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,45 +13,28 @@
 
 // ~ctype();
 
-// UNSUPPORTED: asan, msan
-
 #include <locale>
 #include <cassert>
-#include <new>
-
-unsigned delete_called = 0;
 
-void* operator new[](size_t sz) throw(std::bad_alloc)
-{
-    return operator new(sz);
-}
-
-void operator delete[](void* p) throw()
-{
-    operator delete(p);
-    ++delete_called;
-}
+#include "count_new.hpp"
 
 int main()
 {
     {
-        delete_called = 0;
         std::locale l(std::locale::classic(), new std::ctype<char>);
-        assert(delete_called == 0);
+        assert(globalMemCounter.checkDeleteArrayCalledEq(0));
     }
-    assert(delete_called == 0);
+    assert(globalMemCounter.checkDeleteArrayCalledEq(0));
     {
         std::ctype<char>::mask table[256];
-        delete_called = 0;
         std::locale l(std::locale::classic(), new std::ctype<char>(table));
-        assert(delete_called == 0);
+        assert(globalMemCounter.checkDeleteArrayCalledEq(0));
     }
-    assert(delete_called == 0);
+    assert(globalMemCounter.checkDeleteArrayCalledEq(0));
     {
-        delete_called = 0;
         std::locale l(std::locale::classic(),
             new std::ctype<char>(new std::ctype<char>::mask[256], true));
-        assert(delete_called == 0);
+        assert(globalMemCounter.checkDeleteArrayCalledEq(0));
     }
-    assert(delete_called == 1);
+    assert(globalMemCounter.checkDeleteArrayCalledEq(1));
 }

Modified: libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp Mon Dec 22 16:38:59 2014
@@ -17,43 +17,26 @@
 //     // unspecified
 // };
 
-// UNSUPPORTED: asan, msan
-
 // Not a portable test
 
 #include <codecvt>
 #include <cstdlib>
 #include <cassert>
 
-int outstanding_news = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++outstanding_news;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    if (p)
-    {
-        --outstanding_news;
-        std::free(p);
-    }
-}
+#include "count_new.hpp"
 
 int main()
 {
-    assert(outstanding_news == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
         typedef std::codecvt_utf16<wchar_t> C;
         C c;
-        assert(outstanding_news == 0);
+        assert(globalMemCounter.checkOutstandingNewEq(0));
     }
     {
         typedef std::codecvt_utf16<wchar_t> C;
         std::locale loc(std::locale::classic(), new C);
-        assert(outstanding_news != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(outstanding_news == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }

Modified: libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp Mon Dec 22 16:38:59 2014
@@ -17,43 +17,26 @@
 //     // unspecified
 // };
 
-// UNSUPPORTED: asan, msan
-
 // Not a portable test
 
 #include <codecvt>
 #include <cstdlib>
 #include <cassert>
 
-int outstanding_news = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++outstanding_news;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    if (p)
-    {
-        --outstanding_news;
-        std::free(p);
-    }
-}
+#include "count_new.hpp"
 
 int main()
 {
-    assert(outstanding_news == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
         typedef std::codecvt_utf8<wchar_t> C;
         C c;
-        assert(outstanding_news == 0);
+        assert(globalMemCounter.checkOutstandingNewEq(0));
     }
     {
         typedef std::codecvt_utf8<wchar_t> C;
         std::locale loc(std::locale::classic(), new C);
-        assert(outstanding_news != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(outstanding_news == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }

Modified: libcxx/trunk/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp Mon Dec 22 16:38:59 2014
@@ -14,27 +14,12 @@
 // wbuffer_convert(streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt,
 //                 state_type state = state_type());
 
-// UNSUPPORTED: asan, msan
-
 #include <locale>
 #include <codecvt>
 #include <sstream>
 #include <cassert>
-#include <new>
-
-int new_called = 0;
 
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 int main()
 {
@@ -46,28 +31,28 @@ int main()
     {
         B b;
         assert(b.rdbuf() == nullptr);
-        assert(new_called != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
         std::stringstream s;
         B b(s.rdbuf());
         assert(b.rdbuf() == s.rdbuf());
-        assert(new_called != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
         std::stringstream s;
         B b(s.rdbuf(), new std::codecvt_utf8<wchar_t>);
         assert(b.rdbuf() == s.rdbuf());
-        assert(new_called != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
         std::stringstream s;
         B b(s.rdbuf(), new std::codecvt_utf8<wchar_t>, std::mbstate_t());
         assert(b.rdbuf() == s.rdbuf());
-        assert(new_called != 0);
+        assert(globalMemCounter.checkOutstandingNewNotEq(0));
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }

Modified: libcxx/trunk/test/std/localization/locales/locale/locale.cons/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locales/locale/locale.cons/default.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locales/locale/locale.cons/default.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locales/locale/locale.cons/default.pass.cpp Mon Dec 22 16:38:59 2014
@@ -11,27 +11,11 @@
 
 // locale() throw();
 
-// UNSUPPORTED: asan, msan
-
 #include <locale>
-#include <new>
 #include <cassert>
 
 #include "platform_support.h" // locale name macros
-
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 void check(const std::locale& loc)
 {
@@ -73,19 +57,19 @@ int main()
     int ok;
     {
         std::locale loc;
-        assert(new_called == 0);
+        assert(globalMemCounter.checkOutstandingNewEq(0));
         assert(loc.name() == "C");
-        assert(new_called == 0);
+        assert(globalMemCounter.checkOutstandingNewEq(0));
         check(loc);
-        assert(new_called == 0);
+        assert(globalMemCounter.checkOutstandingNewEq(0));
         assert(std::locale::global(std::locale(LOCALE_en_US_UTF_8)) == loc);
-        ok = new_called;
+        ok = globalMemCounter.outstanding_new;
         std::locale loc2;
-        assert(new_called == ok);
+        assert(globalMemCounter.checkOutstandingNewEq(ok));
         check(loc2);
-        assert(new_called == ok);
+        assert(globalMemCounter.checkOutstandingNewEq(ok));
         assert(loc2 == std::locale(LOCALE_en_US_UTF_8));
-        assert(new_called == ok);
+        assert(globalMemCounter.checkOutstandingNewEq(ok));
     }
-    assert(new_called == ok);
+    assert(globalMemCounter.checkOutstandingNewEq(ok));
 }

Modified: libcxx/trunk/test/std/localization/locales/locale/locale.members/combine.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/localization/locales/locale/locale.members/combine.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/localization/locales/locale/locale.members/combine.pass.cpp (original)
+++ libcxx/trunk/test/std/localization/locales/locale/locale.members/combine.pass.cpp Mon Dec 22 16:38:59 2014
@@ -11,25 +11,10 @@
 
 // template <class Facet> locale combine(const locale& other) const;
 
-// UNSUPPORTED: asan, msan
-
 #include <locale>
-#include <new>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 void check(const std::locale& loc)
 {
@@ -89,7 +74,7 @@ int main()
         const my_facet& f = std::use_facet<my_facet>(loc3);
         assert(f.test() == 5);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }
 {
     {
@@ -104,6 +89,6 @@ int main()
         {
         }
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }
 }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp Mon Dec 22 16:38:59 2014
@@ -14,26 +14,12 @@
 // template <MoveConstructible  R, MoveConstructible ... ArgTypes>
 //   void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
 
-// UNSUPPORTED: asan, msan
 
 #include <functional>
-#include <new>
 #include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -73,65 +59,65 @@ int h(int) {return 1;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = A(1);
     std::function<int(int)> f2 = A(2);
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f1.target<A>()->id() == 1);
     assert(f2.target<A>()->id() == 2);
     swap(f1, f2);
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f1.target<A>()->id() == 2);
     assert(f2.target<A>()->id() == 1);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = A(1);
     std::function<int(int)> f2 = g;
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f1.target<A>()->id() == 1);
     assert(*f2.target<int(*)(int)>() == g);
     swap(f1, f2);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(*f1.target<int(*)(int)>() == g);
     assert(f2.target<A>()->id() == 1);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = g;
     std::function<int(int)> f2 = A(1);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(*f1.target<int(*)(int)>() == g);
     assert(f2.target<A>()->id() == 1);
     swap(f1, f2);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f1.target<A>()->id() == 1);
     assert(*f2.target<int(*)(int)>() == g);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = g;
     std::function<int(int)> f2 = h;
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(*f1.target<int(*)(int)>() == g);
     assert(*f2.target<int(*)(int)>() == h);
     swap(f1, f2);
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(*f1.target<int(*)(int)>() == h);
     assert(*f2.target<int(*)(int)>() == g);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,10 @@
 
 // function(nullptr_t);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -67,34 +51,34 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = (int (*)(int))0;
     assert(!f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     }
     {
     std::function<int(const A*, int)> f = &A::foo;
     assert(f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int (A::*)(int) const>() != 0);
     }
 }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp Mon Dec 22 16:38:59 2014
@@ -16,26 +16,10 @@
 //         && Convertible<Callable<F, ArgTypes...>::result_type
 //   operator=(F f);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -70,30 +54,30 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
     f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
     f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
     f = (int (*)(int))0;
     assert(!f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     }
@@ -101,7 +85,7 @@ int main()
     std::function<int(const A*, int)> f;
     f = &A::foo;
     assert(f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int (A::*)(int) const>() != 0);
     }
 }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,28 +13,12 @@
 
 // template<class A> function(allocator_arg_t, const A&, const function&);
 
-// UNSUPPORTED: asan, msan
 
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
 #include "test_allocator.h"
-
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -67,48 +51,48 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), f);
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     std::function<int(int)> f2(std::allocator_arg, test_allocator<int(*)(int)>(), f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>());
     assert(f2.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     non_default_test_allocator<std::function<int(int)>> al(1);
     std::function<int(int)> f2(std::allocator_arg, al, g);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>());
     assert(f2.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     std::function<int(int)> f2(std::allocator_arg, test_allocator<int>(), f);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>() == 0);
     assert(f2.target<A>() == 0);
     }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,11 @@
 
 // template<class A> function(allocator_arg_t, const A&, function&&);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
 #include <cassert>
 
 #include "test_allocator.h"
-
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -64,16 +49,16 @@ int A::count = 0;
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), std::move(f));
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,11 @@
 
 // function(const function& f);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
 #include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -65,65 +50,65 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2 = f;
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     std::function<int(int)> f2 = f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>());
     assert(f2.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     std::function<int(int)> f2 = f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>() == 0);
     assert(f2.target<A>() == 0);
     }
     {
     std::function<int(int)> f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     assert(!f);
     std::function<long(int)> g = f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(g.target<long(*)(int)>() == 0);
     assert(g.target<A>() == 0);
     assert(!g);
     }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2 = std::move(f);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,10 @@
 
 // function& operator=(const function& f);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -65,57 +49,57 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2;
     f2 = f;
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     std::function<int(int)> f2;
     f2 = f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>());
     assert(f2.target<A>() == 0);
     }
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);
     std::function<int(int)> f2;
     f2 = f;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f2.target<int(*)(int)>() == 0);
     assert(f2.target<A>() == 0);
     }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     assert(f.target<int(*)(int)>() == 0);
     std::function<int(int)> f2;
     f2 = std::move(f);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f2.target<A>());
     assert(f2.target<int(*)(int)>() == 0);
     assert(f.target<A>() == 0);

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,10 @@
 
 // function& operator=(nullptr_t);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -65,24 +49,24 @@ int g(int) {return 0;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f = A();
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f.target<A>());
     f = nullptr;
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<A>() == 0);
     }
     {
     std::function<int(int)> f = g;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>());
     assert(f.target<A>() == 0);
     f = nullptr;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(f.target<int(*)(int)>() == 0);
     }
 }

Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,26 +13,10 @@
 
 // void swap(function& other);
 
-// UNSUPPORTED: asan, msan
-
 #include <functional>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 class A
 {
@@ -72,65 +56,65 @@ int h(int) {return 1;}
 
 int main()
 {
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = A(1);
     std::function<int(int)> f2 = A(2);
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f1.target<A>()->id() == 1);
     assert(f2.target<A>()->id() == 2);
     f1.swap(f2);
     assert(A::count == 2);
-    assert(new_called == 2);
+    assert(globalMemCounter.checkOutstandingNewEq(2));
     assert(f1.target<A>()->id() == 2);
     assert(f2.target<A>()->id() == 1);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = A(1);
     std::function<int(int)> f2 = g;
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f1.target<A>()->id() == 1);
     assert(*f2.target<int(*)(int)>() == g);
     f1.swap(f2);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(*f1.target<int(*)(int)>() == g);
     assert(f2.target<A>()->id() == 1);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = g;
     std::function<int(int)> f2 = A(1);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(*f1.target<int(*)(int)>() == g);
     assert(f2.target<A>()->id() == 1);
     f1.swap(f2);
     assert(A::count == 1);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(f1.target<A>()->id() == 1);
     assert(*f2.target<int(*)(int)>() == g);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     {
     std::function<int(int)> f1 = g;
     std::function<int(int)> f2 = h;
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(*f1.target<int(*)(int)>() == g);
     assert(*f2.target<int(*)(int)>() == h);
     f1.swap(f2);
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(*f1.target<int(*)(int)>() == h);
     assert(*f2.target<int(*)(int)>() == g);
     }
     assert(A::count == 0);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
 }

Modified: libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp Mon Dec 22 16:38:59 2014
@@ -12,27 +12,10 @@
 // allocator:
 // pointer allocate(size_type n, allocator<void>::const_pointer hint=0);
 
-// UNSUPPORTED: asan, msan
-
 #include <memory>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    assert(s == 3 * sizeof(int));
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 int A_constructed = 0;
 
@@ -47,19 +30,23 @@ struct A
 int main()
 {
     std::allocator<A> a;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(A_constructed == 0);
+    globalMemCounter.last_new_size = 0;
     A* ap = a.allocate(3);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
     assert(A_constructed == 0);
     a.deallocate(ap, 3);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(A_constructed == 0);
 
+    globalMemCounter.last_new_size = 0;
     A* ap2 = a.allocate(3, (const void*)5);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
     assert(A_constructed == 0);
     a.deallocate(ap2, 3);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(A_constructed == 0);
 }

Modified: libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp Mon Dec 22 16:38:59 2014
@@ -12,27 +12,10 @@
 // allocator:
 // template <class... Args> void construct(pointer p, Args&&... args);
 
-// UNSUPPORTED: asan, msan
-
 #include <memory>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_called = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_called;
-    assert(s == 3 * sizeof(int));
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    --new_called;
-    std::free(p);
-}
+#include "count_new.hpp"
 
 int A_constructed = 0;
 
@@ -80,76 +63,80 @@ int main()
 {
     {
     std::allocator<A> a;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(A_constructed == 0);
 
+    globalMemCounter.last_new_size = 0;
     A* ap = a.allocate(3);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
     assert(A_constructed == 0);
 
     a.construct(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 0);
 
     a.construct(ap, A());
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 0);
 
     a.construct(ap, 5);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 0);
 
     a.construct(ap, 5, (int*)0);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(A_constructed == 0);
 
     a.deallocate(ap, 3);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(A_constructed == 0);
     }
     {
     std::allocator<move_only> a;
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(move_only_constructed == 0);
 
+    globalMemCounter.last_new_size = 0;
     move_only* ap = a.allocate(3);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
     assert(move_only_constructed == 0);
 
     a.construct(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(move_only_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(move_only_constructed == 0);
 
     a.construct(ap, move_only());
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(move_only_constructed == 1);
 
     a.destroy(ap);
-    assert(new_called == 1);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
     assert(move_only_constructed == 0);
 
     a.deallocate(ap, 3);
-    assert(new_called == 0);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
     assert(move_only_constructed == 0);
     }
 }

Modified: libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp?rev=224741&r1=224740&r2=224741&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp Mon Dec 22 16:38:59 2014
@@ -13,25 +13,10 @@
 
 // template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
-// UNSUPPORTED: asan, msan
-
 #include <memory>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
-int new_count = 0;
-
-void* operator new(std::size_t s) throw(std::bad_alloc)
-{
-    ++new_count;
-    return std::malloc(s);
-}
-
-void  operator delete(void* p) throw()
-{
-    std::free(p);
-}
+#include "count_new.hpp"
 
 struct A
 {
@@ -54,22 +39,22 @@ int A::count = 0;
 
 int main()
 {
-    int nc = new_count;
+    int nc = globalMemCounter.outstanding_new;
     {
     int i = 67;
     char c = 'e';
     std::shared_ptr<A> p = std::make_shared<A>(i, c);
-    assert(new_count == nc+1);
+    assert(globalMemCounter.checkOutstandingNewEq(nc+1));
     assert(A::count == 1);
     assert(p->get_int() == 67);
     assert(p->get_char() == 'e');
     }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    nc = new_count;
+    nc = globalMemCounter.outstanding_new;
     {
     char c = 'e';
     std::shared_ptr<A> p = std::make_shared<A>(67, c);
-    assert(new_count == nc+1);
+    assert(globalMemCounter.checkOutstandingNewEq(nc+1));
     assert(A::count == 1);
     assert(p->get_int() == 67);
     assert(p->get_char() == 'e');

Added: libcxx/trunk/test/support/count_new.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/count_new.hpp?rev=224741&view=auto
==============================================================================
--- libcxx/trunk/test/support/count_new.hpp (added)
+++ libcxx/trunk/test/support/count_new.hpp Mon Dec 22 16:38:59 2014
@@ -0,0 +1,201 @@
+#ifndef COUNT_NEW_HPP
+#define COUNT_NEW_HPP
+
+# include <cstdlib>
+# include <cassert>
+# include <new>
+
+#if  __has_feature(address_sanitizer) \
+  || __has_feature(memory_sanitizer)
+#define DISABLE_NEW_COUNT
+#endif
+
+class MemCounter
+{
+public:
+    // Make MemCounter super hard to accidentally construct or copy.
+    class MemCounterCtorArg_ {};
+    explicit MemCounter(MemCounterCtorArg_) {}
+
+private:
+    MemCounter(MemCounter const &);
+    MemCounter & operator=(MemCounter const &);
+
+public:
+    // All checks return true when disable_checking is enabled.
+    static const bool disable_checking;
+
+    int outstanding_new = 0;
+    int new_called = 0;
+    int delete_called = 0;
+    int last_new_size = 0;
+
+    int outstanding_array_new = 0;
+    int new_array_called = 0;
+    int delete_array_called = 0;
+    int last_new_array_size = 0;
+
+public:
+    void newCalled(std::size_t s)
+    {
+        assert(s);
+        ++new_called;
+        ++outstanding_new;
+        last_new_size = s;
+    }
+
+    void deleteCalled(void * p)
+    {
+        assert(p);
+        --outstanding_new;
+        ++delete_called;
+    }
+
+    void newArrayCalled(std::size_t s)
+    {
+        assert(s);
+        ++outstanding_array_new;
+        ++new_array_called;
+        last_new_array_size = s;
+    }
+
+    void deleteArrayCalled(void * p)
+    {
+        assert(p);
+        --outstanding_array_new;
+        ++delete_array_called;
+    }
+
+    void reset()
+    {
+        outstanding_new = 0;
+        new_called = 0;
+        delete_called = 0;
+        last_new_size = 0;
+
+        outstanding_array_new = 0;
+        new_array_called = 0;
+        delete_array_called = 0;
+        last_new_array_size = 0;
+    }
+
+public:
+    bool checkOutstandingNewEq(int n) const
+    {
+        return disable_checking || n == outstanding_new;
+    }
+
+    bool checkOutstandingNewNotEq(int n) const
+    {
+        return disable_checking || n != outstanding_new;
+    }
+
+    bool checkNewCalledEq(int n) const
+    {
+        return disable_checking || n == new_called;
+    }
+
+    bool checkNewCalledNotEq(int n) const
+    {
+        return disable_checking || n != new_called;
+    }
+
+    bool checkDeleteCalledEq(int n) const
+    {
+        return disable_checking || n == delete_called;
+    }
+
+    bool checkDeleteCalledNotEq(int n) const
+    {
+        return disable_checking || n != delete_called;
+    }
+
+    bool checkLastNewSizeEq(int n) const
+    {
+        return disable_checking || n == last_new_size;
+    }
+
+    bool checkLastNewSizeNotEq(int n) const
+    {
+        return disable_checking || n != last_new_size;
+    }
+
+    bool checkOutstandingArrayNewEq(int n) const
+    {
+        return disable_checking || n == outstanding_array_new;
+    }
+
+    bool checkOutstandingArrayNewNotEq(int n) const
+    {
+        return disable_checking || n != outstanding_array_new;
+    }
+
+    bool checkNewArrayCalledEq(int n) const
+    {
+        return disable_checking || n == new_array_called;
+    }
+
+    bool checkNewArrayCalledNotEq(int n) const
+    {
+        return disable_checking || n != new_array_called;
+    }
+
+    bool checkDeleteArrayCalledEq(int n) const
+    {
+        return disable_checking || n == delete_array_called;
+    }
+
+    bool checkDeleteArrayCalledNotEq(int n) const
+    {
+        return disable_checking || n != delete_array_called;
+    }
+
+    bool checkLastNewArraySizeEq(int n) const
+    {
+        return disable_checking || n == last_new_array_size;
+    }
+
+    bool checkLastNewArraySizeNotEq(int n) const
+    {
+        return disable_checking || n != last_new_array_size;
+    }
+};
+
+#ifdef DISABLE_NEW_COUNT
+  const bool MemCounter::disable_checking = true;
+#else
+  const bool MemCounter::disable_checking = false;
+#endif
+
+MemCounter globalMemCounter((MemCounter::MemCounterCtorArg_()));
+
+#ifndef DISABLE_NEW_COUNT
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+    globalMemCounter.newCalled(s);
+    return std::malloc(s);
+}
+
+void  operator delete(void* p) throw()
+{
+    globalMemCounter.deleteCalled(p);
+    std::free(p);
+}
+
+
+void* operator new[](std::size_t s) throw(std::bad_alloc)
+{
+    globalMemCounter.newArrayCalled(s);
+    return operator new(s);
+}
+
+
+void operator delete[](void* p) throw()
+{
+    globalMemCounter.deleteArrayCalled(p);
+    operator delete(p);
+}
+
+#endif // DISABLE_NEW_COUNT
+
+#endif /* COUNT_NEW_HPP */





More information about the cfe-commits mailing list