[libcxx] [test] Skip alloc counter checks for operations within the libc++ DLL
If libc++ is built as a DLL, calls to operator new within the DLL aren't
overridden if a user provides their own operator in calling code.
Therefore, the alloc counter doesn't pick up on allocations done within
std::string, so skip that check if running on windows. (Technically,
we could keep the checks if running on windows when not built as a DLL,
but trying to keep the conditionals simple.)
Differential Revision: https://reviews.llvm.org/D100219
GitOrigin-RevId: 0e8f5e4a6864839d2292ec1ddfe48b6178c01f85
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
index 201cb99..10f0cf4 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp
@@ -11,8 +11,6 @@
// These tests require locale for non-char paths
// UNSUPPORTED: libcpp-has-no-localization
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
// <filesystem>
// class path
@@ -197,6 +195,9 @@
// required.
// On Windows, the append method is more complex and uses intermediate
// path objects, which causes extra allocations.
+ // In DLL builds on Windows, the overridden operator new won't pick up
+ // allocations done within the DLL, so the RequireAllocationGuard below
+ // won't necessarily see allocations in the cases where they're expected.
#ifdef _WIN32
bool DisableAllocations = false;
#else
@@ -208,6 +209,7 @@
{
RequireAllocationGuard g; // requires 1 or more allocations occur by default
if (DisableAllocations) g.requireExactly(0);
+ else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0));
LHS /= RHS;
}
assert(PathEq(LHS, E));
@@ -219,6 +221,7 @@
{
RequireAllocationGuard g;
if (DisableAllocations) g.requireExactly(0);
+ else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0));
LHS.append(RHS, REnd);
}
assert(PathEq(LHS, E));
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
index 144966c..c13469f 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
@@ -8,8 +8,6 @@
// UNSUPPORTED: c++03
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
// <filesystem>
// class path
@@ -30,7 +28,9 @@
assert(globalMemCounter.checkOutstandingNewEq(0));
const std::string s("we really really really really really really really "
"really really long string so that we allocate");
- assert(globalMemCounter.checkOutstandingNewEq(1));
+ // On windows, the operator new from count_new.h can't override the default
+ // operator for calls within the libc++ DLL.
+ TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkOutstandingNewEq(1)));
const fs::path::string_type ps(s.begin(), s.end());
path p(s);
{
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
index c09d60d..b57ee21 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp
@@ -11,8 +11,6 @@
// These tests require locale for non-char paths
// UNSUPPORTED: libcpp-has-no-localization
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
// <filesystem>
// class path
@@ -142,6 +140,10 @@
// code_cvt conversions.
// For the path native type, no allocations will be performed because no
// conversion is required.
+
+ // In DLL builds on Windows, the overridden operator new won't pick up
+ // allocations done within the DLL, so the RequireAllocationGuard below
+ // won't necessarily see allocations in the cases where they're expected.
bool DisableAllocations = std::is_same<CharT, path::value_type>::value;
{
path LHS(L); PathReserve(LHS, ReserveSize);
@@ -149,6 +151,7 @@
{
RequireAllocationGuard g; // requires 1 or more allocations occur by default
if (DisableAllocations) g.requireExactly(0);
+ else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0));
LHS += RHS;
}
assert(LHS == E);
@@ -160,6 +163,7 @@
{
RequireAllocationGuard g;
if (DisableAllocations) g.requireExactly(0);
+ else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0));
LHS.concat(RHS, REnd);
}
assert(LHS == E);
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
index bf63f70..f0d324b 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
@@ -8,8 +8,6 @@
// UNSUPPORTED: c++03
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
// <filesystem>
// class path
@@ -30,7 +28,9 @@
assert(globalMemCounter.checkOutstandingNewEq(0));
const std::string s("we really really really really really really really "
"really really long string so that we allocate");
- assert(globalMemCounter.checkOutstandingNewEq(1));
+ // On windows, the operator new from count_new.h can't override the default
+ // operator for calls within the libc++ DLL.
+ TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkOutstandingNewEq(1)));
const fs::path::string_type ps(s.begin(), s.end());
path p(s);
{
diff --git a/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp b/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
index b5fe59b..0533bb8 100644
--- a/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
@@ -12,8 +12,6 @@
// ~ctype();
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
#include <locale>
#include <cassert>
@@ -39,7 +37,9 @@
new std::ctype<char>(new std::ctype<char>::mask[256], true));
assert(globalMemCounter.checkDeleteArrayCalledEq(0));
}
- assert(globalMemCounter.checkDeleteArrayCalledEq(1));
+ // On windows, the operator new from count_new.h can't override the default
+ // operator for calls within the libc++ DLL.
+ TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkDeleteArrayCalledEq(1)));
return 0;
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
index 02f19a0..6dfe1ce 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -8,8 +8,6 @@
//
// UNSUPPORTED: libcpp-has-no-threads
-// XFAIL: LIBCXX-WINDOWS-FIXME
-
// <thread>
// class thread
@@ -138,7 +136,7 @@
for (int i=0; i <= numAllocs; ++i) {
throw_one = i;
f_run = false;
- unsigned old_outstanding = outstanding_new;
+ TEST_NOT_WIN32_DLL(unsigned old_outstanding = outstanding_new);
try {
std::thread t(f);
assert(i == numAllocs); // Only final iteration will not throw.
@@ -148,7 +146,9 @@
assert(i < numAllocs);
assert(!f_run); // (2.2)
}
- assert(old_outstanding == outstanding_new); // (2.3)
+ // In DLL builds on Windows, the overridden operators new/delete won't
+ // override calls from within the DLL, so this won't match.
+ TEST_NOT_WIN32_DLL(assert(old_outstanding == outstanding_new)); // (2.3)
}
f_run = false;
throw_one = 0xFFF;
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
index c39e79b..4bd3d55 100644
--- a/test/support/test_macros.h
+++ b/test/support/test_macros.h
@@ -382,6 +382,14 @@
#define TEST_NOT_WIN32(...) __VA_ARGS__
#endif
+#if defined(_WIN32) && !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+#define TEST_NOT_WIN32_DLL(...) ((void)0)
+#define TEST_ONLY_WIN32_DLL(...) __VA_ARGS__
+#else
+#define TEST_NOT_WIN32_DLL(...) __VA_ARGS__
+#define TEST_ONLY_WIN32_DLL(...) ((void)0)
+#endif
+
#ifdef _WIN32
#define TEST_WIN_NO_FILESYSTEM_PERMS_NONE
#endif