diff --git a/CMakeLists.txt b/CMakeLists.txt index f04d3d39c98..d6289e713e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ cmake_minimum_required(VERSION 4.1.1) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) project(msvc_standard_libraries LANGUAGES CXX) -if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.50.35717") - message(FATAL_ERROR "The STL must be built with MSVC Compiler 19.50.35717 or later.") +if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.50.35719") + message(FATAL_ERROR "The STL must be built with MSVC Compiler 19.50.35719 or later.") endif() include(CheckCXXSourceCompiles) @@ -46,7 +46,7 @@ if(TARGET run-validate) add_dependencies(validate run-validate) endif() -option(BUILD_TESTING "Enable testing" ON) +option(CONFIGURE_TESTING "Enable testing" ON) set(VCLIBS_SUFFIX "_oss" CACHE STRING "suffix for built DLL names to avoid conflicts with distributed DLLs") option(STL_USE_ANALYZE "Pass the /analyze flag to MSVC" OFF) @@ -115,7 +115,7 @@ set(VCLIBS_DEBUG_OPTIONS "$<$:/Od>") # TRANSITION, GH-2108: Investigate building the STL with only /O2, not /Os. set(VCLIBS_RELEASE_OPTIONS "$<$:/O2;/Os>") -if(BUILD_TESTING) +if(CONFIGURE_TESTING) add_subdirectory(tests) endif() diff --git a/azure-devops/build-and-test.yml b/azure-devops/build-and-test.yml index 11cf23afa94..250856fb8e1 100644 --- a/azure-devops/build-and-test.yml +++ b/azure-devops/build-and-test.yml @@ -23,9 +23,15 @@ parameters: - name: numShards type: number default: 8 -- name: skipTesting +- name: configureTesting type: boolean - default: false + default: true +- name: buildStl + type: boolean + default: true +- name: runTesting + type: boolean + default: true - name: testsBuildOnly type: boolean default: false @@ -38,7 +44,7 @@ jobs: - template: checkout-self.yml - template: checkout-submodule.yml parameters: - enabled: ${{ not(parameters.skipTesting) }} + enabled: ${{ parameters.configureTesting }} path: 'llvm-project' url: 'https://github.com/llvm/llvm-project.git' - template: checkout-submodule.yml @@ -58,6 +64,8 @@ jobs: targetPlatform: ${{ parameters.targetPlatform }} analyzeBuild: ${{ parameters.analyzeBuild }} asanBuild: ${{ parameters.asanBuild }} + configureTesting: ${{ parameters.configureTesting }} + buildStl: ${{ parameters.buildStl }} testsBuildOnly: ${{ parameters.testsBuildOnly }} - template: build-benchmarks.yml parameters: @@ -79,4 +87,4 @@ jobs: targetArch: ${{ parameters.targetArch }} targetPlatform: ${{ parameters.targetPlatform }} testTargets: ${{ parameters.testTargets }} - skipTesting: ${{ parameters.skipTesting }} + runTesting: ${{ parameters.runTesting }} diff --git a/azure-devops/build-benchmarks.yml b/azure-devops/build-benchmarks.yml index 39bc4a3e325..031e3b2adff 100644 --- a/azure-devops/build-benchmarks.yml +++ b/azure-devops/build-benchmarks.yml @@ -25,7 +25,7 @@ steps: -DSTL_BINARY_DIR="$(buildOutputLocation)" ^ -DVCLIBS_TARGET_ARCHITECTURE=${{ parameters.targetPlatform }} ^ -S $(Build.SourcesDirectory)/benchmarks -B "$(benchmarkBuildOutputLocation)\${{ parameters.compiler }}" - displayName: 'Configure the benchmarks for ${{ parameters.compiler }}' + displayName: 'Configure Benchmarks for ${{ parameters.compiler }}' timeoutInMinutes: 2 env: { TMP: $(tmpDir), TEMP: $(tmpDir) } # TRANSITION, we currently only build the benchmarks with Clang for x64 @@ -36,7 +36,7 @@ steps: - script: | call "$(vsDevCmdBat)" -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo cmake --build "$(benchmarkBuildOutputLocation)\${{ parameters.compiler }}" - displayName: 'Build the benchmarks for ${{ parameters.compiler }}' + displayName: 'Build Benchmarks for ${{ parameters.compiler }}' timeoutInMinutes: 2 env: { TMP: $(tmpDir), TEMP: $(tmpDir) } # TRANSITION, we currently only build the benchmarks with Clang for x64 diff --git a/azure-devops/checkout-self.yml b/azure-devops/checkout-self.yml index 69fbb011639..711c2b00321 100644 --- a/azure-devops/checkout-self.yml +++ b/azure-devops/checkout-self.yml @@ -14,4 +14,4 @@ steps: retryCountOnTaskFailure: 4 - script: | git clean --quiet -x -d -f -f - displayName: 'Clean after checkout' + displayName: 'Clean After Checkout' diff --git a/azure-devops/cmake-configure-build.yml b/azure-devops/cmake-configure-build.yml index d60b672bd3a..8fa87a301c8 100644 --- a/azure-devops/cmake-configure-build.yml +++ b/azure-devops/cmake-configure-build.yml @@ -12,6 +12,10 @@ parameters: type: boolean - name: asanBuild type: boolean +- name: configureTesting + type: boolean +- name: buildStl + type: boolean - name: testsBuildOnly type: boolean - name: litFlags @@ -34,15 +38,17 @@ steps: -DLIT_FLAGS=${{ join(';', parameters.litFlags) }} ^ -DSTL_USE_ANALYZE=${{ parameters.analyzeBuild }} ^ -DSTL_ASAN_BUILD=${{ parameters.asanBuild }} ^ + -DCONFIGURE_TESTING=${{ parameters.configureTesting }} ^ -DTESTS_BUILD_ONLY=${{ parameters.testsBuildOnly }} ^ -DVCLIBS_TARGET_ARCHITECTURE=${{ parameters.targetPlatform }} ^ -S $(Build.SourcesDirectory) -B "$(buildOutputLocation)" - displayName: 'Configure the STL' + displayName: 'Configure STL' timeoutInMinutes: 2 env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - script: | call "$(vsDevCmdBat)" -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo cmake --build "$(buildOutputLocation)" - displayName: 'Build the STL' + displayName: 'Build STL' timeoutInMinutes: 5 + condition: and(succeeded(), ${{ parameters.buildStl }}) env: { TMP: $(tmpDir), TEMP: $(tmpDir) } diff --git a/azure-devops/config.yml b/azure-devops/config.yml index de675864e2d..2c6fd986603 100644 --- a/azure-devops/config.yml +++ b/azure-devops/config.yml @@ -5,10 +5,10 @@ variables: - name: poolName - value: 'Stl-2025-11-17T2154-x64-Pool' + value: 'Stl-2025-11-24T1624-x64-Pool' readonly: true - name: arm64PoolName - value: 'Stl-2025-11-17T2237-arm64-Pool' + value: 'Stl-2025-11-24T1624-arm64-Pool' readonly: true - name: poolDemands value: 'EnableSpotVM -equals false' diff --git a/azure-devops/create-1es-hosted-pool.ps1 b/azure-devops/create-1es-hosted-pool.ps1 index d4ab87f4d04..9a00ad3c3f4 100644 --- a/azure-devops/create-1es-hosted-pool.ps1 +++ b/azure-devops/create-1es-hosted-pool.ps1 @@ -29,8 +29,9 @@ if ($Arch -ieq 'x64') { $ImageOffer = 'WindowsServer' $ImageSku = '2025-datacenter-azure-edition' } else { - $AvailableLocations = @('eastus2', 'northeurope') # Locations where CPP_STL_GitHub has obtained sufficient quota. - $AvailableLocationIdx = 1 # Increment for each new pool, to cycle through the available locations. + # CPP_STL_GitHub has quota for 672 cores (21 VMs) in westcentralus, not currently used. + $AvailableLocations = @('eastus2', 'northeurope') # Locations where CPP_STL_GitHub has quota for 1024 cores (32 VMs). + $AvailableLocationIdx = 2 # Increment for each new pool, to cycle through the available locations. $Location = $AvailableLocations[$AvailableLocationIdx % $AvailableLocations.Length] $VMSize = 'Standard_D32ps_v6' $PoolSize = 32 diff --git a/azure-devops/format-validation.yml b/azure-devops/format-validation.yml index b9345716379..77f3635e5b2 100644 --- a/azure-devops/format-validation.yml +++ b/azure-devops/format-validation.yml @@ -16,7 +16,7 @@ jobs: call "$(vsDevCmdBat)" -host_arch=x64 -arch=x64 -no_logo cmake -G Ninja -S $(Build.SourcesDirectory)/tools -B "$(validationBuildOutputLocation)" cmake --build "$(validationBuildOutputLocation)" - displayName: 'Build format and validation' + displayName: 'Build Validation Tools' timeoutInMinutes: 5 env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - script: | diff --git a/azure-devops/run-tests.yml b/azure-devops/run-tests.yml index 22357e528fe..847adccb36d 100644 --- a/azure-devops/run-tests.yml +++ b/azure-devops/run-tests.yml @@ -10,21 +10,21 @@ parameters: type: string - name: testTargets type: string -- name: skipTesting +- name: runTesting type: boolean steps: - script: | call "$(vsDevCmdBat)" -host_arch=${{ parameters.hostArch }} -arch=${{ parameters.targetArch }} -no_logo ninja --verbose -k 0 ${{ parameters.testTargets }} - displayName: 'Build and Run Tests' + displayName: 'Run Tests' timeoutInMinutes: 30 - condition: and(succeeded(), not(${{ parameters.skipTesting }})) + condition: and(succeeded(), ${{ parameters.runTesting }}) workingDirectory: $(buildOutputLocation) env: { TMP: $(tmpDir), TEMP: $(tmpDir) } - task: PublishTestResults@2 displayName: 'Publish Tests' timeoutInMinutes: 5 - condition: and(succeededOrFailed(), not(${{ parameters.skipTesting }})) + condition: and(succeededOrFailed(), ${{ parameters.runTesting }}) inputs: searchFolder: $(buildOutputLocation) testResultsFormat: JUnit @@ -32,5 +32,5 @@ steps: testRunTitle: 'test-${{ parameters.targetPlatform }}-$(System.JobPositionInPhase)' - publish: $(buildOutputLocation)/test-results.xml artifact: '${{ parameters.targetPlatform }}-$(System.JobPositionInPhase)-xml-$(System.JobId)' - condition: and(failed(), not(${{ parameters.skipTesting }})) + condition: and(failed(), ${{ parameters.runTesting }}) displayName: 'Publish XML Artifact' diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 98f36d52a6b..8776d9901e2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,7 +34,8 @@ stages: analyzeBuild: true buildBenchmarks: true numShards: 1 - skipTesting: true + configureTesting: false + runTesting: false - stage: Build_x86 dependsOn: [] @@ -51,7 +52,8 @@ stages: analyzeBuild: true buildBenchmarks: true numShards: 1 - skipTesting: true + configureTesting: false + runTesting: false - stage: Build_ARM64_Cross dependsOn: [] @@ -68,7 +70,8 @@ stages: analyzeBuild: true buildBenchmarks: true numShards: 1 - skipTesting: true + configureTesting: false + runTesting: false - stage: Build_ARM64EC_Cross dependsOn: [] @@ -85,7 +88,8 @@ stages: analyzeBuild: true buildBenchmarks: true numShards: 1 - skipTesting: true + configureTesting: false + runTesting: false # This ARM64-native build will detect problems with the ARM64 pool as early as possible. # The stage dependencies are structured to optimize the critical path. @@ -104,7 +108,24 @@ stages: analyzeBuild: true buildBenchmarks: true numShards: 1 - skipTesting: true + configureTesting: false + runTesting: false + + - stage: Configure_Tests + dependsOn: [] + displayName: 'Configure Tests' + pool: + name: ${{ variables.poolName }} + demands: ${{ variables.poolDemands }} + jobs: + - template: azure-devops/build-and-test.yml + parameters: + hostArch: x64 + targetArch: x64 + targetPlatform: x64 + numShards: 1 + buildStl: false + runTesting: false - stage: Test_x64 dependsOn: @@ -113,6 +134,7 @@ stages: - Build_x86 - Build_ARM64_Cross - Build_ARM64EC_Cross + - Configure_Tests displayName: 'Test x64' pool: name: ${{ variables.poolName }} diff --git a/llvm-project b/llvm-project index 958cec0ab1b..b725bdba1fa 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 958cec0ab1bbbdc47ea207460de72c5fee24be70 +Subproject commit b725bdba1faf256c725f5fd12c581acb381bf0d3 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 584b4244f2f..1b3bd94e558 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +find_package(Python "3.14.0" REQUIRED COMPONENTS Interpreter) + set(STL_BUILD_ROOT "${PROJECT_BINARY_DIR}/out") set(STL_SOURCE_DIR "${PROJECT_SOURCE_DIR}") set(STL_TEST_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") @@ -23,8 +25,6 @@ add_subdirectory(tr1) # chance to add to the config map and test directory global properties. add_subdirectory(utils/stl-lit) -find_package(Python "3.14.0" REQUIRED COMPONENTS Interpreter) - if(NOT DEFINED LIT_FLAGS) set(LIT_FLAGS "-o" "${CMAKE_CURRENT_BINARY_DIR}/test_results.json") endif() diff --git a/tests/libcxx/CMakeLists.txt b/tests/libcxx/CMakeLists.txt index cdcc763ff3d..bb1a94e5550 100644 --- a/tests/libcxx/CMakeLists.txt +++ b/tests/libcxx/CMakeLists.txt @@ -1,6 +1,11 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +execute_process( + COMMAND "${Python_EXECUTABLE}" "${STL_SOURCE_DIR}/tools/scripts/check_libcxx_paths.py" + COMMAND_ERROR_IS_FATAL ANY +) + set(LIBCXX_ENVLST "${CMAKE_CURRENT_SOURCE_DIR}/usual_matrix.lst") set(LIBCXX_EXPECTED_RESULTS "${CMAKE_CURRENT_SOURCE_DIR}/expected_results.txt") set(LIBCXX_TEST_OUTPUT_DIR "${STL_TEST_OUTPUT_DIR}/libcxx") diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 23dcd2bbca2..88ffdfa720a 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -61,9 +61,6 @@ std/language.support/support.exception/except.nested/ctor_default.pass.cpp:2 SKI # SKIPPED because this is ARM64EC-specific. std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp:2 SKIPPED -# LLVM-160627: [libc++][test] Guard non-guaranteed implicit-lifetime-ness cases with _LIBCPP_VERSION -std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp:2 FAIL - # Non-Standard regex behavior. # "It seems likely that the test is still non-conforming due to how libc++ handles the 'w' character class." std/re/re.traits/lookup_classname.pass.cpp FAIL @@ -574,8 +571,10 @@ std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporar std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp:1 FAIL std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp:0 FAIL std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp:1 FAIL -std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp:0 FAIL -std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp:1 FAIL + +# P2835R7 atomic_ref::address() +# Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. +std/atomics/atomics.ref/address.pass.cpp FAIL # P2944R3 Comparisons For reference_wrapper # Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. @@ -583,9 +582,23 @@ std/utilities/function.objects/refwrap/refwrap.comparisons/compare.three_way.ref std/utilities/function.objects/refwrap/refwrap.comparisons/compare.three_way.refwrap.refwrap_const.pass.cpp FAIL std/utilities/function.objects/refwrap/refwrap.comparisons/compare.three_way.refwrap.refwrap.pass.cpp FAIL +# P2988R12 optional +# Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. +std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp FAIL + +# P3044R2 basic_string::subview() +# Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. +std/strings/basic.string/string.ops/string_substr/subview.pass.cpp FAIL +std/strings/string.view/string.view.ops/subview.pass.cpp FAIL + +# P3060R3 views::indices +# Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. +std/ranges/range.factories/range.iota.view/indices.pass.cpp FAIL + # P3168R2 std::optional Range Support # Add 'std-at-least-c++26' to tests/utils/stl/test/tests.py when beginning work on C++26. std/utilities/optional/optional.iterator/begin.pass.cpp FAIL +std/utilities/optional/optional.iterator/borrowed_range.compile.pass.cpp FAIL std/utilities/optional/optional.iterator/end.pass.cpp FAIL std/utilities/optional/optional.iterator/iterator.pass.cpp FAIL @@ -640,10 +653,6 @@ std/utilities/variant/variant.relops/three_way.pass.cpp:1 FAIL std/algorithms/robust_re_difference_type.compile.pass.cpp:0 FAIL std/algorithms/robust_re_difference_type.compile.pass.cpp:1 FAIL -# DevCom-10026599 VSO-1532879: conditional expression has two different types -std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp:0 FAIL -std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp:1 FAIL - # DevCom-10439137 VSO-1869865: Discarded id-expression causes unnecessary reading std/containers/sequences/array/array.cons/initialization.pass.cpp:0 FAIL std/containers/sequences/array/array.cons/initialization.pass.cpp:1 FAIL @@ -819,21 +828,13 @@ std/input.output/syncstream/syncbuf/syncstream.syncbuf.cons/dtor.pass.cpp FAIL std/input.output/syncstream/syncbuf/syncstream.syncbuf.members/emit.pass.cpp FAIL # GH-5393: : What names can and should regex_traits::lookup_collatename() recognize? -std/re/re.alg/re.alg.match/awk.locale.pass.cpp FAIL std/re/re.alg/re.alg.match/awk.pass.cpp FAIL -std/re/re.alg/re.alg.match/basic.locale.pass.cpp FAIL std/re/re.alg/re.alg.match/basic.pass.cpp FAIL -std/re/re.alg/re.alg.match/ecma.locale.pass.cpp FAIL std/re/re.alg/re.alg.match/ecma.pass.cpp FAIL -std/re/re.alg/re.alg.match/extended.locale.pass.cpp FAIL std/re/re.alg/re.alg.match/extended.pass.cpp FAIL -std/re/re.alg/re.alg.search/awk.locale.pass.cpp FAIL std/re/re.alg/re.alg.search/awk.pass.cpp FAIL -std/re/re.alg/re.alg.search/basic.locale.pass.cpp FAIL std/re/re.alg/re.alg.search/basic.pass.cpp FAIL -std/re/re.alg/re.alg.search/ecma.locale.pass.cpp FAIL std/re/re.alg/re.alg.search/ecma.pass.cpp FAIL -std/re/re.alg/re.alg.search/extended.locale.pass.cpp FAIL std/re/re.alg/re.alg.search/extended.pass.cpp FAIL std/re/re.traits/lookup_collatename.pass.cpp FAIL @@ -896,11 +897,15 @@ std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp SKIPPED std/thread/thread.semaphore/timed.pass.cpp SKIPPED # "This is technically flaky" comments indicate tests with timing assumptions. -# These tests have failed in practice, see VSO-2321213 and VSO-2416940. +# These tests have failed in practice, see VSO-2321213, VSO-2416940, and GH-5899. std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp SKIPPED std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp SKIPPED std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp SKIPPED std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp SKIPPED +std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp SKIPPED +std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp SKIPPED +std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp SKIPPED +std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp SKIPPED # Not analyzed, likely bogus tests. Various assertions, probably POSIX assumptions. std/diagnostics/syserr/syserr.syserr/syserr.syserr.members/ctor_error_code_const_char_pointer.pass.cpp FAIL @@ -1497,17 +1502,16 @@ std/utilities/function.objects/refwrap/common_reference.compile.pass.cpp:1 FAIL std/utilities/meta/meta.trans/meta.trans.other/common_reference.compile.pass.cpp:0 FAIL std/utilities/meta/meta.trans/meta.trans.other/common_reference.compile.pass.cpp:1 FAIL -# Not analyzed. -# MSVC emits truncation warnings, which will be partially addressed by GH-5562. -# Clang asserts `allocated_ == 0 || allocated_ >= i` due to the container proxy object. -std/strings/basic.string/string.capacity/deallocate_size.pass.cpp FAIL - # Not analyzed. MSVC emits warning C4267: 'argument': conversion from 'size_t' to 'unsigned char', possible loss of data std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp:0 FAIL std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp:1 FAIL std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp:0 FAIL std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp:1 FAIL +# Not analyzed. MSVC emits warning C4242: 'argument': conversion from 'int' to 'char', possible loss of data +std/input.output/file.streams/fstreams/filebuf.virtuals/xsputn.pass.cpp:0 FAIL +std/input.output/file.streams/fstreams/filebuf.virtuals/xsputn.pass.cpp:1 FAIL + # *** XFAILS WHICH PASS *** # These tests contain `// XFAIL: msvc` comments, which accurately describe runtime failures for x86 and x64. diff --git a/tests/std/CMakeLists.txt b/tests/std/CMakeLists.txt index 5aa4a346bf9..40bb8eb7b6a 100644 --- a/tests/std/CMakeLists.txt +++ b/tests/std/CMakeLists.txt @@ -1,6 +1,11 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +execute_process( + COMMAND "${Python_EXECUTABLE}" "${STL_SOURCE_DIR}/tools/scripts/check_test_lst_paths.py" "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND_ERROR_IS_FATAL ANY +) + set(STD_EXPECTED_RESULTS "${CMAKE_CURRENT_SOURCE_DIR}/expected_results.txt") set(STD_TEST_OUTPUT_DIR "${STL_TEST_OUTPUT_DIR}/std") diff --git a/tests/std/test.lst b/tests/std/test.lst index 8a583d890a5..c44a4197217 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -1,6 +1,12 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# CUDA is not available in the MSVC-internal test harness: +# tests\GH_000639_nvcc_include_all + +# Needs special machinery to work in the MSVC-internal test harness, not yet implemented: +# tests\GH_002094_cpp_core_guidelines + tests\Dev08_496675_iostream_int_reading tests\Dev08_527068_scl_no_exceptions tests\Dev08_563686_ostream @@ -207,8 +213,6 @@ tests\GH_002030_asan_annotate_vector tests\GH_002039_byte_is_not_trivially_swappable tests\GH_002045_put_time_changes_errno tests\GH_002058_debug_iterator_race -# Needs special machinery to work in the MSVC-internal test harness, not yet implemented: -# tests\GH_002094_cpp_core_guidelines tests\GH_002120_streambuf_seekpos_and_seekoff tests\GH_002168_regex_overflow tests\GH_002206_unreserved_names @@ -417,13 +421,13 @@ tests\P0784R7_library_support_for_more_constexpr_containers tests\P0798R8_monadic_operations_for_std_optional tests\P0811R3_midpoint_lerp tests\P0881R7_stacktrace +tests\P0896R4_and_P1614R2_comparisons tests\P0896R4_common_iterator tests\P0896R4_common_iterator_death tests\P0896R4_counted_iterator tests\P0896R4_counted_iterator_death tests\P0896R4_istream_view tests\P0896R4_istream_view_death -tests\P0896R4_P1614R2_comparisons tests\P0896R4_ranges_alg_adjacent_find tests\P0896R4_ranges_alg_all_of tests\P0896R4_ranges_alg_any_of diff --git a/tests/std/tests/P0896R4_P1614R2_comparisons/env.lst b/tests/std/tests/P0896R4_and_P1614R2_comparisons/env.lst similarity index 100% rename from tests/std/tests/P0896R4_P1614R2_comparisons/env.lst rename to tests/std/tests/P0896R4_and_P1614R2_comparisons/env.lst diff --git a/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp b/tests/std/tests/P0896R4_and_P1614R2_comparisons/test.cpp similarity index 100% rename from tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp rename to tests/std/tests/P0896R4_and_P1614R2_comparisons/test.cpp diff --git a/tests/tr1/CMakeLists.txt b/tests/tr1/CMakeLists.txt index b09e61bbf06..9bedec5f2f4 100644 --- a/tests/tr1/CMakeLists.txt +++ b/tests/tr1/CMakeLists.txt @@ -1,6 +1,11 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +execute_process( + COMMAND "${Python_EXECUTABLE}" "${STL_SOURCE_DIR}/tools/scripts/check_test_lst_paths.py" "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND_ERROR_IS_FATAL ANY +) + set(TR1_EXPECTED_RESULTS "${CMAKE_CURRENT_SOURCE_DIR}/expected_results.txt") set(TR1_TEST_OUTPUT_DIR "${STL_TEST_OUTPUT_DIR}/tr1") diff --git a/tools/scripts/check_libcxx_paths.py b/tools/scripts/check_libcxx_paths.py index 93a4f34b351..7113bf16d67 100644 --- a/tools/scripts/check_libcxx_paths.py +++ b/tools/scripts/check_libcxx_paths.py @@ -13,28 +13,24 @@ # Use the location of this script to find the base of the repo. absolute_repo_path = Path(sys.argv[0]).absolute().parents[2] + expected_results_txt = "tests/libcxx/expected_results.txt" # Tests can be mentioned multiple times for different configurations. # Build up a unique set before checking for existence. - unique_tests = set() + with open(absolute_repo_path / expected_results_txt) as file: + stripped_lines = [line.strip() for line in file] - with open(absolute_repo_path / "tests/libcxx/expected_results.txt") as file: - for line in map(lambda x: x.strip(), file): - if line and not line.startswith("#"): # Ignore empty lines and comments. - unique_tests.add(re.sub(r"(:\d+)? (FAIL|SKIPPED)$", "", line)) + filtered_lines = [s for s in stripped_lines if s and not s.startswith("#")] # Ignore empty lines and comments. + config_rgx = re.compile(r"(:\d+)? (FAIL|SKIPPED)$") + unique_tests = {config_rgx.sub("", line) for line in filtered_lines} # Build up a list of nonexistent tests so they can be printed in sorted order. - nonexistent_tests = [] - - for str in unique_tests: - if not (absolute_repo_path / "llvm-project/libcxx/test" / str).is_file(): - nonexistent_tests.append(str) + absolute_libcxx_test = absolute_repo_path / "llvm-project/libcxx/test" + nonexistent_tests = [str for str in unique_tests if not (absolute_libcxx_test / str).is_file()] if nonexistent_tests: - print(f"Failure, found {len(nonexistent_tests)} nonexistent test paths:") - nonexistent_tests.sort() - for str in nonexistent_tests: - print(f"{str}") + print(f"Failure: {expected_results_txt} contains {len(nonexistent_tests)} nonexistent tests:", file=sys.stderr) + for str in sorted(nonexistent_tests): + print(f"{str}", file=sys.stderr) + print(f"##vso[task.logissue type=error]{expected_results_txt} failed validation, see log.", file=sys.stderr) sys.exit(1) - - print("Success, all test paths exist.") diff --git a/tools/scripts/check_test_lst_paths.py b/tools/scripts/check_test_lst_paths.py new file mode 100644 index 00000000000..e308139258b --- /dev/null +++ b/tools/scripts/check_test_lst_paths.py @@ -0,0 +1,74 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This script checks tests/std/test.lst (and tr1) for duplicate, missing, nonexistent, and unsorted test paths. + +from pathlib import Path +import sys + +def is_nonempty_dir(p: Path) -> bool: + return p.is_dir() and any(p.iterdir()) + +if __name__ == "__main__": + if len(sys.argv) != 2: + sys.exit(f"Usage: python {sys.argv[0]} tests/std-OR-tr1") + + absolute_base = Path(sys.argv[1]).absolute() + absolute_tests = absolute_base / "tests" + absolute_test_lst = absolute_base / "test.lst" + relative_test_lst = absolute_test_lst.relative_to(absolute_test_lst.parents[2]) + + with open(absolute_test_lst) as file: + stripped_lines = [line.strip() for line in file] + + filtered_lines = [s for s in stripped_lines if s and not s.startswith("#")] # Ignore empty lines and comments. + + unique_tests = set() + duplicate_tests = set() + for line in filtered_lines: + if line in unique_tests: + duplicate_tests.add(line) # Repeatedly duplicated tests will be reported only once. + else: + unique_tests.add(line) + + existing_tests = {fR"tests\{p.name}" for p in absolute_tests.iterdir() if is_nonempty_dir(p)} + + commented_tests = { # These tests are commented out. Avoid reporting them as missing. + R"tests\GH_000639_nvcc_include_all", + R"tests\GH_002094_cpp_core_guidelines", + } + + missing_tests = existing_tests - commented_tests - unique_tests + + nonexistent_tests = [str for str in unique_tests if not is_nonempty_dir(absolute_base / str)] + + failed = False + + if duplicate_tests: + failed = True + print(f"Failure: {relative_test_lst} contains {len(duplicate_tests)} duplicate tests:", file=sys.stderr) + for str in sorted(duplicate_tests): + print(f"{str}", file=sys.stderr) + + if missing_tests: + failed = True + print(f"Failure: {relative_test_lst} is missing {len(missing_tests)} tests:", file=sys.stderr) + for str in sorted(missing_tests): + print(f"{str}", file=sys.stderr) + + if nonexistent_tests: + failed = True + print(f"Failure: {relative_test_lst} contains {len(nonexistent_tests)} nonexistent tests:", file=sys.stderr) + for str in sorted(nonexistent_tests): + print(f"{str}", file=sys.stderr) + + for i in range(len(filtered_lines) - 1): # If filtered_lines is empty, range(-1) is empty. + if filtered_lines[i] > filtered_lines[i + 1]: # Use greater-than to avoid reporting adjacent duplicates. + failed = True + print(f"Failure: {relative_test_lst} isn't sorted, starting with:", file=sys.stderr) + print(f"{filtered_lines[i + 1]}", file=sys.stderr) + break # Report only the first unsorted line. + + if failed: + print(f"##vso[task.logissue type=error]{relative_test_lst} failed validation, see log.", file=sys.stderr) + sys.exit(1)