From 0687b2265f5f5b9cb7cf17f47ace27c3d746cdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 15 Jun 2025 01:38:15 +0300 Subject: [PATCH 1/2] [libcxx] [test] Use ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS in more places ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS allows waiving asserts, for cases when we can't count allocations that happen within the libc++ shared library. When compiling with optimization, it is possible that some calls end up generated inline, where the overridden operator new/delete do get called (counting those calls), whereas the compiler may decide to leave some calls to the external definition (inside the shared library, where we can't count the calls). In particular, in one case, a non-optimized build calls _ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev from the DLL, while it gets inlined (including direct calls to operator delete) when built with optimization. Therefore; for the cases where we can't count allocations internally within the library, waive these asserts. This fixes all testcases in mingw mode, when built with optimization enabled. --- libcxx/test/std/containers/sequences/vector/common.h | 8 ++++---- libcxx/test/support/count_new.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libcxx/test/std/containers/sequences/vector/common.h b/libcxx/test/std/containers/sequences/vector/common.h index 4af6559a06e73..34453f8889b73 100644 --- a/libcxx/test/std/containers/sequences/vector/common.h +++ b/libcxx/test/std/containers/sequences/vector/common.h @@ -214,10 +214,10 @@ struct throwing_iterator { }; inline void check_new_delete_called() { - assert(globalMemCounter.new_called == globalMemCounter.delete_called); - assert(globalMemCounter.new_array_called == globalMemCounter.delete_array_called); - assert(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called); - assert(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called); + ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.new_called == globalMemCounter.delete_called); + ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.new_array_called == globalMemCounter.delete_array_called); + ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called); + ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called); } template diff --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h index c8169d3acceab..beb11ee4deae4 100644 --- a/libcxx/test/support/count_new.h +++ b/libcxx/test/support/count_new.h @@ -626,7 +626,7 @@ struct RequireAllocationGuard { void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; } ~RequireAllocationGuard() { - assert(globalMemCounter.checkOutstandingNewEq(static_cast(m_outstanding_new_on_init))); + ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkOutstandingNewEq(static_cast(m_outstanding_new_on_init))); std::size_t Expect = m_new_count_on_init + m_req_alloc; assert(globalMemCounter.checkNewCalledEq(static_cast(Expect)) || (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(static_cast(Expect)))); From 559282fb35e8e3ac65876729c35325fa54110ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 11 Jul 2025 16:22:12 +0300 Subject: [PATCH 2/2] Only do ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS in count_new.h for specific tests --- .../filesystems/class.path/path.member/path.append.pass.cpp | 5 +++++ .../filesystems/class.path/path.member/path.concat.pass.cpp | 5 +++++ libcxx/test/support/count_new.h | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp index 3442019a8360c..b3d96c283c9b7 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp @@ -12,6 +12,11 @@ // These tests require locale for non-char paths // UNSUPPORTED: no-localization +// In MinGW mode, with optimizations enabled with a DLL, the number of counted +// allocations mismatches, as some ctor/dtor calls are generated in the +// calling code, and some are called from the DLL. +// ADDITIONAL_COMPILE_FLAGS: -DALLOW_MISMATCHING_LIBRRARY_INTERNAL_ALLOCATIONS + // // class path diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp index 5596de7328da4..570d303985e86 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp @@ -12,6 +12,11 @@ // These tests require locale for non-char paths // UNSUPPORTED: no-localization +// In MinGW mode, with optimizations enabled with a DLL, the number of counted +// allocations mismatches, as some ctor/dtor calls are generated in the +// calling code, and some are called from the DLL. +// ADDITIONAL_COMPILE_FLAGS: -DALLOW_MISMATCHING_LIBRRARY_INTERNAL_ALLOCATIONS + // // class path diff --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h index beb11ee4deae4..f175bc2ffcd44 100644 --- a/libcxx/test/support/count_new.h +++ b/libcxx/test/support/count_new.h @@ -626,7 +626,11 @@ struct RequireAllocationGuard { void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; } ~RequireAllocationGuard() { +#ifdef ALLOW_MISMATCHING_LIBRRARY_INTERNAL_ALLOCATIONS ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkOutstandingNewEq(static_cast(m_outstanding_new_on_init))); +#else + assert(globalMemCounter.checkOutstandingNewEq(static_cast(m_outstanding_new_on_init))); +#endif std::size_t Expect = m_new_count_on_init + m_req_alloc; assert(globalMemCounter.checkNewCalledEq(static_cast(Expect)) || (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(static_cast(Expect))));