Index: libcxx/test/libcxx/strings/c.strings/version_cuchar.pass.cpp =================================================================== --- libcxx/test/libcxx/strings/c.strings/version_cuchar.pass.cpp +++ libcxx/test/libcxx/strings/c.strings/version_cuchar.pass.cpp @@ -8,6 +8,10 @@ // // XFAIL: * +// Skip this test on windows. If built on top of the MSVC runtime, the +// header actually does exist (although not provided by us). +// UNSUPPORTED: windows + // #include Index: libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class directory_entry @@ -155,7 +153,8 @@ // reading directories; test using a special inaccessible directory // instead. const path dir = GetWindowsInaccessibleDir(); - TEST_REQUIRE(!dir.empty()); + if (dir.empty()) + TEST_UNSUPPORTED(); const path file = dir / "file"; { std::error_code ec = GetTestEC(); Index: libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class directory_iterator @@ -94,7 +92,8 @@ // reading directories; test using a special inaccessible directory // instead. const path testDir = GetWindowsInaccessibleDir(); - TEST_REQUIRE(!testDir.empty()); + if (testDir.empty()) + TEST_UNSUPPORTED(); #else scoped_test_env env; path const testDir = env.make_env_path("dir1"); Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp +++ libcxx/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 - // // class path Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp +++ libcxx/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 - // // class path Index: libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class directory_iterator @@ -95,7 +93,8 @@ // reading directories; test using a special inaccessible directory // instead. const path testDir = GetWindowsInaccessibleDir(); - TEST_REQUIRE(!testDir.empty()); + if (testDir.empty()) + TEST_UNSUPPORTED(); #else scoped_test_env env; path const testDir = env.make_env_path("dir1"); Index: libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp +++ libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // bool exists(file_status s) noexcept @@ -91,7 +89,8 @@ // reading directories; test using a special inaccessible directory // instead. const path p = GetWindowsInaccessibleDir(); - TEST_REQUIRE(!p.empty()); + if (p.empty()) + TEST_UNSUPPORTED(); #else scoped_test_env env; const path dir = env.create_dir("dir"); Index: libcxx/test/std/language.support/support.dynamic/alloc.errors/set.new.handler/set_new_handler.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/alloc.errors/set.new.handler/set_new_handler.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/alloc.errors/set.new.handler/set_new_handler.pass.cpp @@ -8,8 +8,6 @@ // test set_new_handler -// XFAIL: LIBCXX-WINDOWS-FIXME - #include #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp @@ -22,11 +22,6 @@ // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// On Windows libc++ doesn't provide its own definitions for new/delete -// but instead depends on the ones in VCRuntime. However VCRuntime does not -// yet provide aligned new/delete definitions so this test fails to link. -// XFAIL: LIBCXX-WINDOWS-FIXME - // test operator new #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp @@ -22,11 +22,6 @@ // XFAIL: with_system_cxx_lib=macosx10.10 // XFAIL: with_system_cxx_lib=macosx10.9 -// On Windows libc++ doesn't provide its own definitions for new/delete -// but instead depends on the ones in VCRuntime. However VCRuntime does not -// yet provide aligned new/delete definitions so this test fails to compile/link. -// XFAIL: LIBCXX-WINDOWS-FIXME - // test operator new (nothrow) #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp @@ -9,7 +9,6 @@ // test operator new[] // NOTE: asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: LIBCXX-WINDOWS-FIXME #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp @@ -9,7 +9,6 @@ // test operator new [] (nothrow) // NOTE: asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: LIBCXX-WINDOWS-FIXME #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp @@ -10,7 +10,6 @@ // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: LIBCXX-WINDOWS-FIXME #include #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp @@ -22,11 +22,6 @@ // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// On Windows libc++ doesn't provide its own definitions for new/delete -// but instead depends on the ones in VCRuntime. However VCRuntime does not -// yet provide aligned new/delete definitions so this test fails to compile/link. -// XFAIL: LIBCXX-WINDOWS-FIXME - // test operator new #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp @@ -22,11 +22,6 @@ // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// On Windows libc++ doesn't provide its own definitions for new/delete -// but instead depends on the ones in VCRuntime. However VCRuntime does not -// yet provide aligned new/delete definitions so this test fails to compile/link. -// XFAIL: LIBCXX-WINDOWS-FIXME - // test operator new (nothrow) #include Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp +++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp @@ -10,7 +10,6 @@ // asan and msan will not call the new handler. // UNSUPPORTED: sanitizer-new-delete -// XFAIL: LIBCXX-WINDOWS-FIXME #include #include Index: libcxx/test/std/strings/c.strings/cuchar.pass.cpp =================================================================== --- libcxx/test/std/strings/c.strings/cuchar.pass.cpp +++ libcxx/test/std/strings/c.strings/cuchar.pass.cpp @@ -8,6 +8,10 @@ // // XFAIL: libc++ +// Skip this test on windows. If built on top of the MSVC runtime, the +// header actually does exist (although not provided by us). +// UNSUPPORTED: windows + // #include Index: libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp =================================================================== --- libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp +++ libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp @@ -28,10 +28,15 @@ int test0 = 0; int test1 = 0; int test2 = 0; +int f1ready = 0; +int f2ready = 0; +std::condition_variable main_cv; void f1() { std::unique_lock lk(mut); + f1ready = 1; + main_cv.notify_one(); assert(test1 == 0); while (test1 == 0) cv.wait(lk); @@ -42,6 +47,8 @@ void f2() { std::unique_lock lk(mut); + f2ready = 1; + main_cv.notify_one(); assert(test2 == 0); while (test2 == 0) cv.wait(lk); @@ -56,6 +63,8 @@ std::this_thread::sleep_for(std::chrono::milliseconds(100)); { std::unique_locklk(mut); + while (!f1ready || !f2ready) + main_cv.wait(lk); test1 = 1; test2 = 1; } Index: libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp =================================================================== --- libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp +++ libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp @@ -44,9 +44,12 @@ test1 = 1; cv.notify_one(); Clock::time_point t0 = Clock::now(); - while (test2 == 0 && - cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout) - ; + Clock::time_point wait_end = t0 + milliseconds(250); + Clock::time_point now; + do { + now = Clock::now(); + if (now >= wait_end) break; + } while (test2 == 0 && cv.wait_for(lk, wait_end - now) == std::cv_status::no_timeout); Clock::time_point t1 = Clock::now(); if (runs == 0) { Index: libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp =================================================================== --- libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp +++ libcxx/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp @@ -47,9 +47,12 @@ test1 = 1; cv.notify_one(); Clock::time_point t0 = Clock::now(); - while (test2 == 0 && - cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout) - ; + Clock::time_point wait_end = t0 + milliseconds(250); + Clock::time_point now; + do { + now = Clock::now(); + if (now >= wait_end) break; + } while (test2 == 0 && cv.wait_for(lk, wait_end - now) == std::cv_status::no_timeout); Clock::time_point t1 = Clock::now(); if (runs == 0) { Index: libcxx/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp =================================================================== --- libcxx/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp +++ libcxx/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp @@ -17,8 +17,6 @@ // UNSUPPORTED: with_system_cxx_lib=macosx10.10 // UNSUPPORTED: with_system_cxx_lib=macosx10.9 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // file_clock Index: libcxx/test/support/filesystem_test_helper.h =================================================================== --- libcxx/test/support/filesystem_test_helper.h +++ libcxx/test/support/filesystem_test_helper.h @@ -678,22 +678,28 @@ const fs::path dir("C:\\System Volume Information"); std::error_code ec; const fs::path root("C:\\"); - fs::directory_iterator it(root, ec); - if (ec) - return fs::path(); - const fs::directory_iterator endIt{}; - while (it != endIt) { - const fs::directory_entry &ent = *it; - if (ent == dir) { - // Basic sanity checks on the directory_entry - if (!ent.exists()) - return fs::path(); - if (!ent.is_directory()) - return fs::path(); - return ent; + for (const auto &ent : fs::directory_iterator(root, ec)) { + if (ent != dir) + continue; + // Basic sanity checks on the directory_entry + if (!ent.exists() || !ent.is_directory()) { + fprintf(stderr, "The expected inaccessible directory \"%s\" was found " + "but doesn't behave as expected, skipping tests " + "regarding it\n", dir.string().c_str()); + return fs::path(); } - ++it; + // Check that it indeed is inaccessible as expected + (void)fs::exists(ent, ec); + if (!ec) { + fprintf(stderr, "The expected inaccessible directory \"%s\" was found " + "but seems to be accessible, skipping tests " + "regarding it\n", dir.string().c_str()); + return fs::path(); + } + return ent; } + fprintf(stderr, "No inaccessible directory \"%s\" found, skipping tests " + "regarding it\n", dir.string().c_str()); return fs::path(); } Index: libcxx/utils/ci/buildkite-pipeline.yml =================================================================== --- libcxx/utils/ci/buildkite-pipeline.yml +++ libcxx/utils/ci/buildkite-pipeline.yml @@ -288,6 +288,21 @@ - exit_status: -1 # Agent was lost limit: 2 + - label: "Windows" + # TODO: The CI runner doesn't have bash in the path currently. Once it + # has that, remove the absolute path and just call 'bash' here. + command: "\"\\Program Files\\Git\\usr\\bin\\bash\" libcxx/utils/ci/run-buildbot generic-win" + artifact_paths: + - "**/test-results.xml" + agents: + queue: "windows" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + soft_fail: + - exit_status: 1 + # All jobs defined before this `wait` will run whenever a CI job is started. # Jobs defined after the `wait` will run only if all the jobs above succeeded. # We use this to reduce the load on testers that have more constrained resources Index: libcxx/utils/ci/run-buildbot =================================================================== --- libcxx/utils/ci/run-buildbot +++ libcxx/utils/ci/run-buildbot @@ -426,6 +426,49 @@ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake" check-cxx-cxxabi ;; +generic-win) + clean + # TODO: The CI runner doesn't have bash in the path currently, and it's + # needed for running tests. Once it's available out of the box, remove this. + export PATH="$PATH:/c/Program Files/Git/usr/bin" + + # TODO: Clang-cl in MSVC configurations don't have access to compiler_rt + # builtins helpers for int128 division. See + # https://reviews.llvm.org/D91139#2429595 for a comment about longterm + # intent for handling the issue. In the meantime, define + # -D_LIBCPP_HAS_NO_INT128 (both when building the library itself and + # when building tests) to allow enabling filesystem for running tests, + # even if it uses a non-permanent ABI. + + # TODO: The CI runner currently uses Clang 11, which doesn't implicitly + # link in oldnames.lib (which is needed for some tests) when compiling + # with the plain "clang" driver, as the tests do (as opposed to using + # the "clang-cl" driver for compiling). When the CI runner runs + # Clang 12, the "-loldnames" option can be dropped. + + # TODO: Currently, building with the experimental library breaks running + # tests (the test linking look for the c++experimental library with the + # wrong name, and the statically linked c++experimental can't be linked + # correctly when libc++ visibility attributes indicate dllimport linkage + # anyway), thus just disable the experimental library. Remove this + # setting when cmake and the test driver does the right thing automatically. + + echo "--- Generating CMake" + cmake -S "${MONOREPO_ROOT}/libcxx" \ + -B "${BUILD_DIR}" \ + -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_C_COMPILER=clang-cl \ + -DCMAKE_CXX_COMPILER=clang-cl \ + -DLLVM_LIT_ARGS="-sv --show-unsupported --xunit-xml-output test-results.xml" \ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO \ + -DLIBCXX_ENABLE_FILESYSTEM=YES \ + -DCMAKE_CXX_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ + -DLIBCXX_TEST_COMPILER_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ + -DLIBCXX_TEST_LINKER_FLAGS="-loldnames" + echo "+++ Running the libc++ tests" + ${NINJA} -vC "${BUILD_DIR}" check-cxx +;; *) echo "${BUILDER} is not a known configuration" exit 1 Index: libcxx/utils/libcxx/test/config.py =================================================================== --- libcxx/utils/libcxx/test/config.py +++ libcxx/utils/libcxx/test/config.py @@ -473,7 +473,7 @@ elif cxx_abi == 'vcruntime': debug_suffix = 'd' if self.debug_build else '' self.cxx.link_flags += ['-l%s%s' % (lib, debug_suffix) for lib in - ['vcruntime', 'ucrt', 'msvcrt']] + ['vcruntime', 'ucrt', 'msvcrt', 'msvcprt']] elif cxx_abi == 'none' or cxx_abi == 'default': if self.target_info.is_windows(): debug_suffix = 'd' if self.debug_build else ''