From 305346e72828582070dc3566efdb0e3a910682a1 Mon Sep 17 00:00:00 2001 From: Alex Prabhat Bara <50404684+alexprabhat99@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:19:05 +0530 Subject: [PATCH 01/33] update C++20 section of for WG21-P3136R1 Retiring Niebloids (#5191) --- stl/inc/yvals_core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ea6762d0d2d..ce83ff45727 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -314,6 +314,7 @@ // P2905R2 Runtime Format Strings // P2909R4 Fix Formatting Of Code Units As Integers // P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts +// P3136R1 Retiring Niebloids // _HAS_CXX20 indirectly controls: // P0619R4 Removing C++17-Deprecated Features From 90820002693fe6eaaec2e55884472c654186207e Mon Sep 17 00:00:00 2001 From: Justin Goshi Date: Tue, 17 Dec 2024 15:54:42 -1000 Subject: [PATCH 02/33] Add support for running only edg tests (#5194) --- tests/CMakeLists.txt | 1 + tests/utils/stl/test/params.py | 3 +++ tests/utils/stl/test/tests.py | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 980ddcf194b..51c1dbae1f5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,3 +34,4 @@ get_property(STL_LIT_TEST_DIRS GLOBAL PROPERTY STL_LIT_TEST_DIRS) add_custom_target(STL-CI COMMAND ${STL_LIT_COMMAND} -Dnotags=ASAN ${STL_LIT_TEST_DIRS} USES_TERMINAL) add_custom_target(STL-ASan-CI COMMAND ${STL_LIT_COMMAND} -Dtags=ASAN ${STL_LIT_TEST_DIRS} USES_TERMINAL) +add_custom_target(test-only-edg COMMAND ${STL_LIT_COMMAND} -Dnotags=ASAN -Dtest-only-edg=True --xunit-xml-output test-results.xml ${STL_LIT_TEST_DIRS} USES_TERMINAL) diff --git a/tests/utils/stl/test/params.py b/tests/utils/stl/test/params.py index c3dd091d5d5..77997337673 100644 --- a/tests/utils/stl/test/params.py +++ b/tests/utils/stl/test/params.py @@ -58,6 +58,9 @@ def beNice(prio: str) -> list[ConfigAction]: def getDefaultParameters(config, litConfig): DEFAULT_PARAMETERS = [ + Parameter(name='test-only-edg', choices=[True, False], type=bool, default=False, + help="Whether to only run edg tests (those that use the /BE flag).", + actions=lambda enabled: [AddFeature(name='test-only-edg')] if enabled else []), Parameter(name='long_tests', choices=[True, False], type=bool, default=True, help="Whether to run tests that take a long time. This can be useful when running on a slow device.", actions=lambda enabled: [AddFeature(name='long_tests')] if enabled else []), diff --git a/tests/utils/stl/test/tests.py b/tests/utils/stl/test/tests.py index 7217d49bab2..4e1b99eba5c 100644 --- a/tests/utils/stl/test/tests.py +++ b/tests/utils/stl/test/tests.py @@ -71,9 +71,12 @@ def configureTest(self, litConfig): return Result(UNSUPPORTED, "Test does not require any of the features specified in limit_to_features: %s" % msg) + if 'test-only-edg' in self.config.available_features and 'edg' not in self.requires: + return Result(UNSUPPORTED, 'We run only /BE tests with the test-only-edg flag') + if 'edg_drop' in self.config.available_features: - if not 'edg' in self.requires: - return Result(UNSUPPORTED, 'We only run /BE tests with the edg drop') + if 'edg' not in self.requires: + return Result(UNSUPPORTED, 'We run only /BE tests with the edg drop') _, tmpBase = self.getTempPaths() self.isenseRspPath = tmpBase + '.isense.rsp' From ca2b2c65f98862685deb344a2e4de15a5a8dcb03 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 7 Jan 2025 01:21:28 -0800 Subject: [PATCH 03/33] Revert "Maybe Clang _does_ work with `ALTERNATENAME` (#5098)" (#5224) --- stl/inc/xcall_once.h | 3 +- .../GH_002030_asan_annotate_string/env.lst | 76 ++++++++++++------- .../GH_002030_asan_annotate_vector/env.lst | 72 +++++++++++------- 3 files changed, 94 insertions(+), 57 deletions(-) diff --git a/stl/inc/xcall_once.h b/stl/inc/xcall_once.h index 8874e232f81..7d484899160 100644 --- a/stl/inc/xcall_once.h +++ b/stl/inc/xcall_once.h @@ -40,7 +40,8 @@ union _Immortalizer_impl { // constructs _Ty, never destroys _Ty _Storage; }; -#if defined(_M_CEE) || defined(_M_ARM64EC) || defined(_M_HYBRID) +#if defined(_M_CEE) || defined(_M_ARM64EC) || defined(_M_HYBRID) \ + || defined(__clang__) // TRANSITION, avoid /ALTERNATENAME for Clang, see GH-5224 #define _WINDOWS_API __stdcall #define _RENAME_WINDOWS_API(_Api) _Api##_clr #else // ^^^ use forwarders / use /ALTERNATENAME vvv diff --git a/tests/std/tests/GH_002030_asan_annotate_string/env.lst b/tests/std/tests/GH_002030_asan_annotate_string/env.lst index 08acc3dc792..9ea027b4346 100644 --- a/tests/std/tests/GH_002030_asan_annotate_string/env.lst +++ b/tests/std/tests/GH_002030_asan_annotate_string/env.lst @@ -9,32 +9,50 @@ RUNALL_INCLUDE ..\prefix.lst RUNALL_CROSSLIST PM_CL="/Zi /wd4611 /w14640 /Zc:threadSafeInit-" PM_LINK="/debug" RUNALL_CROSSLIST -PM_CL="-fsanitize=address" -PM_CL="/D_ANNOTATE_STRING" -RUNALL_CROSSLIST -PM_CL="/BE /c /EHsc /MD /std:c++14" -PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" -PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" -PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_CL="/EHsc /MD /std:c++14" -PM_CL="/EHsc /MD /std:c++14 /Zc:char8_t" -PM_CL="/EHsc /MD /std:c++17" -PM_CL="/EHsc /MD /std:c++17 /Zc:char8_t" -PM_CL="/EHsc /MD /std:c++20" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" -PM_CL="/EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" -PM_CL="/EHsc /MDd /std:c++17 /permissive-" -PM_CL="/EHsc /MDd /std:c++20 /permissive-" -PM_CL="/EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" -PM_CL="/EHsc /MDd /std:c++latest /permissive-" -PM_CL="/EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MT /std:c++latest /permissive-" -PM_CL="/EHsc /MTd /std:c++latest /permissive" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" -PM_CL="/EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /BE /c /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /EHsc /MD /std:c++17" +PM_CL="-fsanitize=address /EHsc /MD /std:c++20" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++20 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_STRING /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++14 /Zc:char8_t" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++17" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++17 /Zc:char8_t" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++20" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="/D_ANNOTATE_STRING /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MDd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MT /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="/D_ANNOTATE_STRING /EHsc /MTd /std:c++latest /permissive-" +# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_STRING without -fsanitize=address +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" diff --git a/tests/std/tests/GH_002030_asan_annotate_vector/env.lst b/tests/std/tests/GH_002030_asan_annotate_vector/env.lst index 4182c344a2e..e644474d29a 100644 --- a/tests/std/tests/GH_002030_asan_annotate_vector/env.lst +++ b/tests/std/tests/GH_002030_asan_annotate_vector/env.lst @@ -8,30 +8,48 @@ RUNALL_INCLUDE ..\prefix.lst RUNALL_CROSSLIST PM_CL="/Zi /wd4611 /w14640 /Zc:threadSafeInit-" PM_LINK="/debug" RUNALL_CROSSLIST -PM_CL="-fsanitize=address" -PM_CL="/D_ANNOTATE_VECTOR" -RUNALL_CROSSLIST -PM_CL="/BE /c /EHsc /MD /std:c++14" -PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" -PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" -PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_CL="/EHsc /MD /std:c++14" -PM_CL="/EHsc /MD /std:c++17" -PM_CL="/EHsc /MD /std:c++20" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" -PM_CL="/EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" -PM_CL="/EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" -PM_CL="/EHsc /MDd /std:c++17 /permissive-" -PM_CL="/EHsc /MDd /std:c++20 /permissive-" -PM_CL="/EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" -PM_CL="/EHsc /MDd /std:c++latest /permissive-" -PM_CL="/EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MT /std:c++latest /permissive-" -PM_CL="/EHsc /MTd /std:c++latest /permissive" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" -PM_CL="/EHsc /MTd /std:c++latest /permissive- /fp:strict" -PM_CL="/EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /BE /c /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="-fsanitize=address /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MD /std:c++14" +PM_CL="-fsanitize=address /EHsc /MD /std:c++17" +PM_CL="-fsanitize=address /EHsc /MD /std:c++20" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++17 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++20 /permissive-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="-fsanitize=address /EHsc /MDd /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MT /std:c++latest /permissive-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="-fsanitize=address /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MT /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /BE /c /EHsc /MTd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++14" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++17" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++20" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++latest /permissive- /Zc:char8_t- /Zc:preprocessor" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MD /std:c++latest /permissive- /Zc:noexceptTypes-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++14 /fp:except /Zc:preprocessor" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++17 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++20 /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++latest /permissive- /Zc:wchar_t-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MDd /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MT /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MT /std:c++latest /permissive-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive- /analyze:only /analyze:autolog-" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive- /fp:strict" +PM_CL="/D_ANNOTATE_VECTOR /EHsc /MTd /std:c++latest /permissive-" +# TRANSITION, we don't use /ALTERNATENAME for Clang (see GH-5224) so we cannot test /D_ANNOTATE_VECTOR without -fsanitize=address +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++17" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" +PM_COMPILER="clang-cl" PM_CL="-fsanitize=address -fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict" From 76c41da13c029f3b125c922a03bd7ec0a5a2eb75 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 7 Jan 2025 17:25:10 +0800 Subject: [PATCH 04/33] Implement LWG-3900 The `allocator_arg_t` overloads of `generator::promise_type::operator new` should not be constrained (#5150) Co-authored-by: Casey Carter --- stl/inc/generator | 6 ++++-- tests/std/tests/P2502R2_generator_promise/test.cpp | 10 ++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/stl/inc/generator b/stl/inc/generator index 8e5d94619d9..8b3a9d30260 100644 --- a/stl/inc/generator +++ b/stl/inc/generator @@ -110,16 +110,18 @@ namespace _Gen_detail { } template - requires convertible_to _NODISCARD_RAW_PTR_ALLOC static void* operator new( const size_t _Size, allocator_arg_t, const _Alloc2& _Al, const _Args&...) { + static_assert(convertible_to, + "Allocator argument must be convertible to the allocator type (N5001 [coro.generator.promise]/18)"); return _Allocate(static_cast<_Alloc>(static_cast<_Proto_allocator>(_Al)), _Size); } template - requires convertible_to _NODISCARD_RAW_PTR_ALLOC static void* operator new( const size_t _Size, const _This&, allocator_arg_t, const _Alloc2& _Al, const _Args&...) { + static_assert(convertible_to, + "Allocator argument must be convertible to the allocator type (N5001 [coro.generator.promise]/18)"); return _Allocate(static_cast<_Alloc>(static_cast<_Proto_allocator>(_Al)), _Size); } diff --git a/tests/std/tests/P2502R2_generator_promise/test.cpp b/tests/std/tests/P2502R2_generator_promise/test.cpp index 42a2f7c09ea..7cd4a2323b2 100644 --- a/tests/std/tests/P2502R2_generator_promise/test.cpp +++ b/tests/std/tests/P2502R2_generator_promise/test.cpp @@ -78,9 +78,8 @@ void test_operator_new(typename Gen::promise_type& p, const Alloc2& alloc2 = {}) } // Test 'operator new(size_t, allocator_arg_t, const Alloc2&, const Args&...)' - constexpr bool has_op_new2 = HasOperatorNew; - static_assert(has_op_new2 == (same_as || convertible_to) ); - if constexpr (has_op_new2) { + // This operator new is unconstrained. + if constexpr (same_as || convertible_to) { const size_t size = __STDCPP_DEFAULT_NEW_ALIGNMENT__; void* const mem = p.operator new(size, allocator_arg, alloc2, 0, 0); assert(reinterpret_cast(mem) % __STDCPP_DEFAULT_NEW_ALIGNMENT__ == 0); @@ -88,10 +87,9 @@ void test_operator_new(typename Gen::promise_type& p, const Alloc2& alloc2 = {}) } // Test 'operator new(size_t, const This&, allocator_arg_t, const Alloc2&, const Args&...)' + // This operator new is unconstrained. struct S {}; - constexpr bool has_op_new3 = HasOperatorNew; - static_assert(has_op_new3 == (same_as || convertible_to) ); - if constexpr (has_op_new3) { + if constexpr (same_as || convertible_to) { const size_t size = __STDCPP_DEFAULT_NEW_ALIGNMENT__; const S s; void* const mem = p.operator new(size, s, allocator_arg, alloc2, 0, 0); From 13a64795f8ce58105504166eac3e67bc7db262ca Mon Sep 17 00:00:00 2001 From: "Thomas A. Fabrizio" Date: Tue, 7 Jan 2025 04:27:50 -0500 Subject: [PATCH 05/33] Update N4993 to N5001 in README.md (#5196) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de703daad4e..23176d4326b 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ issue. The [bug tag][] and [enhancement tag][] are being populated. # Goals -We're implementing the latest C++ Working Draft, currently [N4993][], which will eventually become the next C++ +We're implementing the latest C++ Working Draft, currently [N5001][], which will eventually become the next C++ International Standard. The terms Working Draft (WD) and Working Paper (WP) are interchangeable; we often informally refer to these drafts as "the Standard" while being aware of the difference. (There are other relevant Standards; for example, supporting `/std:c++14` and `/std:c++17` involves understanding how the C++14 and C++17 @@ -565,7 +565,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception [LWG issues]: https://cplusplus.github.io/LWG/lwg-toc.html [LWG tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3ALWG [Microsoft Open Source Code of Conduct]: https://opensource.microsoft.com/codeofconduct/ -[N4993]: https://wg21.link/N4993 +[N5001]: https://wg21.link/N5001 [NOTICE.txt]: NOTICE.txt [Ninja]: https://ninja-build.org [STL-CI-badge]: https://dev.azure.com/vclibs/STL/_apis/build/status%2FSTL-CI?branchName=main "STL-CI" From 4c78eee03640f7b2b3eaf67d49f81b64e7a915f2 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 7 Jan 2025 02:06:00 -0800 Subject: [PATCH 06/33] [test] Don't repeatedly warn about a compiler not being found (#5199) --- tests/utils/stl/test/tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/utils/stl/test/tests.py b/tests/utils/stl/test/tests.py index 4e1b99eba5c..658db996127 100644 --- a/tests/utils/stl/test/tests.py +++ b/tests/utils/stl/test/tests.py @@ -30,6 +30,8 @@ class TestType(Flag): class STLTest(Test): + compilerNotFound = set() + def __init__(self, suite, pathInSuite, litConfig, testConfig, envlstEntry, envNum): self.envNum = envNum self.envlstEntry = envlstEntry @@ -217,7 +219,9 @@ def _handleEnvlst(self, litConfig): _compilerPathCache[envCompiler] = cxx if not cxx: - litConfig.warning('Could not find: %r' % envCompiler) + if envCompiler not in self.compilerNotFound: + self.compilerNotFound.add(envCompiler) + litConfig.warning('Could not find: %r' % envCompiler) return Result(SKIPPED, 'This test was skipped because the compiler, "' + envCompiler + '", could not be found') From 04081522161549b18fa0b0fae0d2a531ee967958 Mon Sep 17 00:00:00 2001 From: Alex Prabhat Bara <50404684+alexprabhat99@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:37:28 +0530 Subject: [PATCH 07/33] Update _MSVC_STL_UPDATE to January 2025 (#5217) --- stl/inc/yvals_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ce83ff45727..913e728b71a 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -915,7 +915,7 @@ #define _CPPLIB_VER 650 #define _MSVC_STL_VERSION 143 -#define _MSVC_STL_UPDATE 202412L +#define _MSVC_STL_UPDATE 202501L #ifndef _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH #if defined(__CUDACC__) && defined(__CUDACC_VER_MAJOR__) From af0bd0020485f5bbea9a82f8904311e984fbe359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 08:38:32 +0100 Subject: [PATCH 08/33] ``: Fix character range bounds in case-insensitive regexes (#5164) --- stl/inc/regex | 33 +++++++++---------- .../test.cpp | 27 +++++++++++++++ 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index b5fa6cae395..9b179e7275f 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1499,7 +1499,7 @@ public: void _Add_char(_Elem _Ch); void _Add_class(); void _Add_char_to_class(_Elem _Ch); - void _Add_range(_Elem _Ex0, _Elem _Ex1); + void _Add_range2(_Elem, _Elem); void _Add_named_class(_Regex_traits_base::char_class_type, bool = false); void _Add_equiv(_FwdIt, _FwdIt, _Difft); void _Add_coll(_FwdIt, _FwdIt, _Difft); @@ -2882,19 +2882,12 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_class(_Elem _Ch) { // add } template -void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range(_Elem _Arg0, _Elem _Arg1) { +void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _Elem _Arg1) { // add character range to set - unsigned int _Ex0; - unsigned int _Ex1; - if (_Flags & regex_constants::icase) { // change to lowercase range - _Ex0 = static_cast(_Traits.translate_nocase(_Arg0)); - _Ex1 = static_cast(_Traits.translate_nocase(_Arg1)); - } else { - _Ex0 = static_cast(_Arg0); - _Ex1 = static_cast(_Arg1); - } - + unsigned int _Ex0 = static_cast(_Arg0); + const unsigned int _Ex1 = static_cast(_Arg1); _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current); + for (; _Ex0 <= _Ex1 && _Ex1 < _Get_bmax(); ++_Ex0) { // set a bit if (!_Node->_Small) { _Node->_Small = new _Bitmap; @@ -2913,7 +2906,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range(_Elem _Arg0, _Elem _Arg1) { } _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex0)); - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex1)); + _Node->_Ranges->_Insert(_Arg1); } } } @@ -4113,16 +4106,22 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_ClassRanges() { // check for valid clas _Error(regex_constants::error_range); // set precedes or follows dash } - if (_Flags & regex_constants::collate) { // translate ends of range - _Val = _Traits.translate(static_cast<_Elem>(_Val)); + _Elem _Chr2 = static_cast<_Elem>(_Val); + + // translate ends of range + if (_Flags & regex_constants::icase) { + _Chr1 = _Traits.translate_nocase(_Chr1); + _Chr2 = _Traits.translate_nocase(_Chr2); + } else if (_Flags & regex_constants::collate) { _Chr1 = _Traits.translate(_Chr1); + _Chr2 = _Traits.translate(_Chr2); } - if (static_cast(_Val) < static_cast(_Chr1)) { + if (static_cast(_Chr2) < static_cast(_Chr1)) { _Error(regex_constants::error_range); } - _Nfa._Add_range(_Chr1, static_cast<_Elem>(_Val)); + _Nfa._Add_range2(_Chr1, _Chr2); } else if (_Ret == _Prs_chr) { _Nfa._Add_char_to_class(static_cast<_Elem>(_Val)); } diff --git a/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp b/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp index ab6f047f9b6..26a8f89605d 100644 --- a/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp +++ b/tests/std/tests/Dev10_814245_regex_character_class_crash/test.cpp @@ -111,12 +111,39 @@ void test_VSO_984741_splitting_a_string_with_a_regex() { assert(equal(i, sregex_token_iterator{}, begin(tokens), end(tokens))); } +void test_gh_5164_case_insensitive_ranges() { + using ch_traits = char_traits; + const regex_traits re_traits; + for (size_t upper = 0; upper < characterCount; ++upper) { + for (size_t lower = 0; lower < characterCount; ++lower) { + const string pattern(g_firstCharacters[lower] + "-" + g_secondCharacters[upper]); + const char left_bound = re_traits.translate_nocase(g_inputs[lower][0]); + const char right_bound = re_traits.translate_nocase(g_inputs[upper][0]); + + if (ch_traits::lt(right_bound, left_bound)) { + g_regexTester.should_throw(pattern, error_range, icase); + } else { + const regex r(pattern, icase); + for (size_t c = 0; c < characterCount; ++c) { + const char input_icase = re_traits.translate_nocase(g_inputs[c][0]); + if (ch_traits::lt(input_icase, left_bound) || ch_traits::lt(right_bound, input_icase)) { + g_regexTester.should_not_match(g_inputs[c], pattern, r); + } else { + g_regexTester.should_match(g_inputs[c], pattern, r); + } + } + } + } + } +} + int main() { init_character_strings(); test_dev10_814245_character_class_should_not_crash(); test_dev10_723057_normal_to_high_bit_ranges_should_not_throw_error_range(); test_VSO_153556_singular_classes_can_have_high_bit_set(); test_VSO_984741_splitting_a_string_with_a_regex(); + test_gh_5164_case_insensitive_ranges(); return g_regexTester.result(); } From bbd15badf3d99c7d1378fa9b8e9a3c282972b304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 08:44:08 +0100 Subject: [PATCH 09/33] ``: Limit backreference parsing to single digit for basic regular expressions (#5167) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 24 +++++++++---------- .../std/tests/VSO_0000000_regex_use/test.cpp | 15 ++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 9b179e7275f..29383d77fc1 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1187,8 +1187,6 @@ _NODISCARD bool operator!=(const match_results<_BidIt, _Alloc>& _Left, const mat } #endif // !_HAS_CXX20 -_INLINE_VAR constexpr unsigned int _BRE_MAX_GRP = 9U; - _INLINE_VAR constexpr unsigned int _Bmp_max = 256U; // must fit in an unsigned int _INLINE_VAR constexpr unsigned int _Bmp_shift = 3U; _INLINE_VAR constexpr unsigned int _Bmp_chrs = 1U << _Bmp_shift; // # of bits to be stored in each char @@ -1705,7 +1703,7 @@ private: // parsing int _Do_digits(int _Base, int _Count, regex_constants::error_type _Error_type); - bool _DecimalDigits(regex_constants::error_type _Error_type); + bool _DecimalDigits2(regex_constants::error_type _Error_type, int _Count = INT_MAX); void _HexDigits(int); bool _OctalDigits(); void _Do_ex_class(_Meta_type); @@ -3943,9 +3941,9 @@ int _Parser<_FwdIt, _Elem, _RxTraits>::_Do_digits( } template -bool _Parser<_FwdIt, _Elem, _RxTraits>::_DecimalDigits( - regex_constants::error_type _Error_type) { // check for decimal value - return _Do_digits(10, INT_MAX, _Error_type) != INT_MAX; +bool _Parser<_FwdIt, _Elem, _RxTraits>::_DecimalDigits2( + const regex_constants::error_type _Error_type, const int _Count /* = INT_MAX */) { // check for decimal value + return _Do_digits(10, _Count, _Error_type) != _Count; } template @@ -4034,7 +4032,7 @@ _Prs_ret _Parser<_FwdIt, _Elem, _RxTraits>::_ClassEscape2() { // check for class return _Prs_chr; } else if ((_L_flags & _L_esc_wsd) && _CharacterClassEscape(false)) { return _Prs_set; - } else if (_DecimalDigits(regex_constants::error_escape)) { // check for invalid value + } else if (_DecimalDigits2(regex_constants::error_escape)) { // check for invalid value if (_Val != 0) { _Error(regex_constants::error_escape); } @@ -4332,15 +4330,17 @@ bool _Parser<_FwdIt, _Elem, _RxTraits>::_CharacterEscape() { // check for valid template void _Parser<_FwdIt, _Elem, _RxTraits>::_AtomEscape() { // check for valid atom escape - if ((_L_flags & _L_bckr) && _DecimalDigits(regex_constants::error_backref)) { // check for valid back reference + constexpr int _Bre_max_backref_digits = 1; + if ((_L_flags & _L_bckr) + && _DecimalDigits2(regex_constants::error_backref, + (_L_flags & _L_lim_bckr) ? _Bre_max_backref_digits : INT_MAX)) { // check for valid back reference if (_Val == 0) { // handle \0 if (!(_L_flags & _L_bzr_chr)) { _Error(regex_constants::error_escape); } else { _Nfa._Add_char(static_cast<_Elem>(_Val)); } - } else if (((_L_flags & _L_lim_bckr) && _BRE_MAX_GRP < static_cast(_Val)) - || _Grp_idx < static_cast(_Val) || _Finished_grps.size() <= static_cast(_Val) + } else if (_Grp_idx < static_cast(_Val) || _Finished_grps.size() <= static_cast(_Val) || !_Finished_grps[static_cast(_Val)]) { _Error(regex_constants::error_backref); } else { @@ -4364,7 +4364,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Quantifier() { // check for quantifier _Max = 1; } else if (_Mchar == _Meta_lbr) { // check for valid bracketed value _Next(); - if (!_DecimalDigits(regex_constants::error_badbrace)) { + if (!_DecimalDigits2(regex_constants::error_badbrace)) { _Error(regex_constants::error_badbrace); } @@ -4374,7 +4374,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Quantifier() { // check for quantifier } else { // check for decimal constant following comma _Next(); if (_Mchar != _Meta_rbr) { - if (!_DecimalDigits(regex_constants::error_badbrace)) { + if (!_DecimalDigits2(regex_constants::error_badbrace)) { _Error(regex_constants::error_badbrace); } diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index ad2efc0d4a6..7f1528039ab 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -669,6 +669,20 @@ void test_gh_5160() { neg_regex.should_search_fail(L"xxxYxx\x2009xxxZxxx"); // U+2009 THIN SPACE } +void test_gh_5167() { + // GH-5167: Limit backreference parsing to single digit for basic regular expressions + g_regexTester.should_match("abab0", R"(\(ab*\)\10)", basic); + g_regexTester.should_match("abab0", R"(\(ab*\)\10)", grep); + g_regexTester.should_match("abbcdccdc5abb8", R"(\(ab*\)\([cd]*\)\25\18)", basic); + g_regexTester.should_match("abbcdccdc5abb8", R"(\(ab*\)\([cd]*\)\25\18)", grep); + g_regexTester.should_not_match("abbcdccdc5abb8", R"(\(ab*\)\([cd]*\)\15\28)", basic); + g_regexTester.should_not_match("abbcdccdc5abb8", R"(\(ab*\)\([cd]*\)\15\28)", grep); + g_regexTester.should_throw(R"(abc\1d)", error_backref, basic); + g_regexTester.should_throw(R"(abc\1d)", error_backref, grep); + g_regexTester.should_throw(R"(abc\10)", error_backref, basic); + g_regexTester.should_throw(R"(abc\10)", error_backref, grep); +} + int main() { test_dev10_449367_case_insensitivity_should_work(); test_dev11_462743_regex_collate_should_not_disable_regex_icase(); @@ -699,6 +713,7 @@ int main() { test_gh_4995(); test_gh_5058(); test_gh_5160(); + test_gh_5167(); return g_regexTester.result(); } From 3b6d29cf39762e04b18ee681a7b06c6ff5d539e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 09:29:30 +0100 Subject: [PATCH 10/33] ``: Fix integer overflow in `_Buf` and implement geometric buffer expansion (#5175) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 29383d77fc1..f3ecd9dfd5f 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1193,7 +1193,6 @@ _INLINE_VAR constexpr unsigned int _Bmp_chrs = 1U << _Bmp_shift; // # of bits t _INLINE_VAR constexpr unsigned int _Bmp_mask = _Bmp_chrs - 1U; _INLINE_VAR constexpr unsigned int _Bmp_size = (_Bmp_max + _Bmp_chrs - 1U) / _Bmp_chrs; -_INLINE_VAR constexpr unsigned int _Buf_incr = 16U; _INLINE_VAR constexpr unsigned int _ARRAY_THRESHOLD = 4U; enum _Node_flags : int { // flags for nfa nodes with special properties @@ -1255,9 +1254,9 @@ struct _Buf { // character buffer return _Chrs; } - void _Insert(_Elem _Ch) { // append _Ch + void _Insert2(_Elem _Ch) { // append _Ch if (_Sz <= _Nchrs) { - _Expand(_Nchrs + _Buf_incr); + _Expand2(1U); } _Chrs[_Nchrs++] = _Ch; @@ -1268,17 +1267,43 @@ struct _Buf { // character buffer } template - void _Insert(_FwdIt _First, _FwdIt _Last) { // append multiple characters + void _Insert2(_FwdIt _First, _FwdIt _Last) { // append multiple characters while (_First != _Last) { - _Insert(*_First++); + _Insert2(*_First++); } } private: - void _Expand(unsigned int _Len) { // expand buffer to hold _Len characters - _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, _Get_size_of_n(_Len))); + unsigned int _Calculate_expansion(unsigned int _Increase) const { + constexpr size_t _Max_elems = static_cast(-1) / sizeof(_Elem); + constexpr unsigned int _Max_uint = static_cast(-1); + constexpr unsigned int _Max = _Max_elems < _Max_uint ? static_cast(_Max_elems) : _Max_uint; + + constexpr unsigned int _Buf_incr = 16U; + + if (_Increase < _Buf_incr) { + _Increase = _Buf_incr; + } + + if (_Increase < (_Sz >> 1)) { + _Increase = _Sz >> 1; + } + + if (_Max <= _Increase || _Max - _Increase <= _Sz) { + return _Max; + } + + return _Sz + _Increase; + } + + void _Expand2(const unsigned int _Min_increase) { // expand buffer by at least _Min_increase + const unsigned int _Len = _Calculate_expansion(_Min_increase); + if (_Len - _Sz < _Min_increase) { + _Xregex_error(regex_constants::error_space); + } + _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, sizeof(_Elem) * static_cast(_Len))); if (!_Tmp) { - _Xbad_alloc(); + _Xregex_error(regex_constants::error_space); } _Chrs = _Tmp; @@ -2833,7 +2858,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char(_Elem _Ch) { // append charac } _Node_str<_Elem>* _Node = static_cast<_Node_str<_Elem>*>(_Current); - _Node->_Data._Insert(_Ch); + _Node->_Data._Insert2(_Ch); } template @@ -2867,7 +2892,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_array(_Elem _Ch) { // appe _Node->_Large = new _Buf<_Elem>; } - _Node->_Large->_Insert(_Ch); + _Node->_Large->_Insert2(_Ch); } template @@ -2903,8 +2928,8 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _E _Node->_Ranges = new _Buf<_Elem>; } - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex0)); - _Node->_Ranges->_Insert(_Arg1); + _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex0)); + _Node->_Ranges->_Insert2(_Arg1); } } } @@ -2948,7 +2973,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Char_to_elts(_FwdIt _First, _FwdIt _La *_Cur = new _Sequence<_Elem>(static_cast(_Diff)); (*_Cur)->_Next = _Node; } - (*_Cur)->_Data._Insert(_First, _Last); + (*_Cur)->_Data._Insert2(_First, _Last); } template From 247c51fd45467f229361d4eea26781311a765506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 09:35:44 +0100 Subject: [PATCH 11/33] ``: Correct characters not matched by special character dot (#5192) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 19 +++++++++- .../std/tests/VSO_0000000_regex_use/test.cpp | 37 +++++++++++++++++++ tests/tr1/tests/regex3/test.cpp | 17 +++------ 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index f3ecd9dfd5f..58b0a2a16f1 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -79,6 +79,8 @@ enum _Meta_type : int { // meta character representations for parser _Meta_nl = '\n', _Meta_cr = '\r', _Meta_bsp = '\b', + _Meta_ls = L'\u2028', + _Meta_ps = L'\u2029', _Meta_chr = 0, _Esc_bsl = '\\', @@ -3523,10 +3525,23 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c break; case _N_dot: - if (_Tgt_state._Cur == _End || *_Tgt_state._Cur == _Meta_nl || *_Tgt_state._Cur == _Meta_cr) { + if (_Tgt_state._Cur == _End) { _Failed = true; } else { - ++_Tgt_state._Cur; + const _Elem _Ch = *_Tgt_state._Cur; + if (_Sflags + & (regex_constants::basic | regex_constants::extended | regex_constants::grep + | regex_constants::egrep | regex_constants::awk)) { + if (_Ch == _Elem()) { + _Failed = true; + } + } else if (_Ch == _Meta_nl || _Ch == _Meta_cr || _Ch == _Meta_ls || _Ch == _Meta_ps) { // ECMAScript + _Failed = true; + } + + if (!_Failed) { + ++_Tgt_state._Cur; + } } break; diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index 7f1528039ab..e7e10070ab3 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -683,6 +683,42 @@ void test_gh_5167() { g_regexTester.should_throw(R"(abc\10)", error_backref, grep); } +void test_gh_5192() { + // GH-5192: Correct characters not matched by special character dot + for (const syntax_option_type option : { + regex_constants::basic, + regex_constants::extended, + regex_constants::awk, + regex_constants::grep, + regex_constants::egrep, + }) { + const test_regex caretDotStar(&g_regexTester, "^.*", option); + caretDotStar.should_search_match("abc\nd\re\0f"s, "abc\nd\re"s); + caretDotStar.should_search_match("abcd\re\ngh\0i"s, "abcd\re\ngh"s); + + const test_wregex wCaretDotStar(&g_regexTester, L"^.*", option); + wCaretDotStar.should_search_match(L"abc\nd\re\0f"s, L"abc\nd\re"s); + wCaretDotStar.should_search_match(L"abcd\re\ngh\0i"s, L"abcd\re\ngh"s); + wCaretDotStar.should_search_match(L"abc\u2028d\ne\0f"s, L"abc\u2028d\ne"s); // U+2028 LINE SEPARATOR + wCaretDotStar.should_search_match(L"abc\u2029d\ne\0f"s, L"abc\u2029d\ne"s); // U+2029 PARAGRAPH SEPARATOR + } + + for (const syntax_option_type option : { + regex_constants::ECMAScript, + syntax_option_type(), + }) { + const test_regex caretDotStar(&g_regexTester, "^.*", option); + caretDotStar.should_search_match("ab\0c\nd\re\0f"s, "ab\0c"s); + caretDotStar.should_search_match("ab\0cd\re\ngh\0i"s, "ab\0cd"s); + + const test_wregex wCaretDotStar(&g_regexTester, L"^.*", option); + wCaretDotStar.should_search_match(L"abc\0\nd\re\0f"s, L"abc\0"s); + wCaretDotStar.should_search_match(L"ab\0cd\re\ngh\0i"s, L"ab\0cd"s); + wCaretDotStar.should_search_match(L"ab\0c\u2028d\ne\0f"s, L"ab\0c"s); // U+2028 LINE SEPARATOR + wCaretDotStar.should_search_match(L"a\0bc\u2029d\ne\0f"s, L"a\0bc"s); // U+2029 PARAGRAPH SEPARATOR + } +} + int main() { test_dev10_449367_case_insensitivity_should_work(); test_dev11_462743_regex_collate_should_not_disable_regex_icase(); @@ -714,6 +750,7 @@ int main() { test_gh_5058(); test_gh_5160(); test_gh_5167(); + test_gh_5192(); return g_regexTester.result(); } diff --git a/tests/tr1/tests/regex3/test.cpp b/tests/tr1/tests/regex3/test.cpp index 1c9c9465cf4..05cd644c1d0 100644 --- a/tests/tr1/tests/regex3/test.cpp +++ b/tests/tr1/tests/regex3/test.cpp @@ -321,17 +321,12 @@ static void test_uncoveredgrammar() { STDString str2(T("Prime number")); STDString str3(T("aaaqxzbbb")); STDString str4(T("aaa\nxzbbb")); - static const STD regex_constants::syntax_option_type flag[6] = { - STD regex_constants::ECMAScript, - STD regex_constants::basic, - STD regex_constants::extended, - STD regex_constants::awk, - STD regex_constants::grep, - STD regex_constants::egrep, - }; - for (int i = 0; i <= 5; i++) { - rx1.assign(T(".*"), flag[i]); - rx2.assign(T("aaa...bbb"), flag[i]); + for (const STD regex_constants::syntax_option_type flag : { + STD regex_constants::ECMAScript, + STD regex_constants::syntax_option_type(), + }) { + rx1.assign(T(".*"), flag); + rx2.assign(T("aaa...bbb"), flag); CHECK(!STD regex_match(str1, rx1)); CHECK(STD regex_match(str2, rx1)); CHECK(STD regex_match(str3, rx2)); From 615ce660a73b41bbc84af797f49b2dc53c35236a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 09:43:54 +0100 Subject: [PATCH 12/33] ``: Simplify `regex_traits<_Elem>::translate(_Elem)` (#5209) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 58b0a2a16f1..edb154a9657 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -295,8 +295,7 @@ public: } _Elem translate(_Elem _Ch) const { // provide locale-sensitive mapping - string_type _Res = _Getcoll()->transform(_STD addressof(_Ch), _STD addressof(_Ch) + 1); - return _Res.size() == 1 ? _Res[0] : _Ch; + return _Ch; } _Elem translate_nocase(_Elem _Ch) const { // provide case-insensitive mapping From 30dd267b6f369610fe4a1835111fef09c50126fc Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 16:46:58 +0800 Subject: [PATCH 13/33] ``: Fix pointer-size constructor of `basic_regex` and remove `error_parse` (#5211) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 24 ++++++++++--------- .../test.compile.pass.cpp | 1 + .../std/tests/VSO_0000000_regex_use/test.cpp | 12 ++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index edb154a9657..2b041163fa7 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -151,7 +151,7 @@ namespace regex_constants { error_badrepeat, error_complexity, error_stack, - error_parse, + _Error_parse, // TRANSITION, was error_parse, keeping behavior error_syntax }; } // namespace regex_constants @@ -465,12 +465,12 @@ _EXPORT_STD class _NODISCARD regex_error : public runtime_error { // type of all public: explicit regex_error(regex_constants::error_type _Ex) : runtime_error(_Stringify(_Ex)), _Err(_Ex) {} - _NODISCARD regex_constants::error_type code() const { + _NODISCARD regex_constants::error_type code() const noexcept /* strengthened */ { return _Err; } private: - static const char* _Stringify(regex_constants::error_type _Ex) { // map error code to string + static const char* _Stringify(regex_constants::error_type _Ex) noexcept { // map error code to string switch (_Ex) { // select known error_type message case regex_constants::error_collate: return "regex_error(error_collate): The expression " @@ -516,7 +516,7 @@ private: return "regex_error(error_stack): There was insufficient " "memory to determine whether the regular expression " "could match the specified character sequence."; - case regex_constants::error_parse: + case regex_constants::_Error_parse: // TRANSITION, keeping behavior return "regex_error(error_parse)"; case regex_constants::error_syntax: return "regex_error(error_syntax)"; @@ -1844,12 +1844,10 @@ public: } basic_regex(_In_reads_(_Count) const _Elem* _Ptr, size_t _Count, flag_type _Flags = regex_constants::ECMAScript) { - if (_Ptr) { - _Reset(_Ptr, _Ptr + _Count, _Flags); - return; - } - - _Xregex_error(regex_constants::error_parse); +#if _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(_Ptr != nullptr || _Count == 0, "constructing basic_regex from an invalid range"); +#endif // ^^^ _ITERATOR_DEBUG_LEVEL != 0 ^^^ + _Reset(_Ptr, _Ptr + _Count, _Flags); } template @@ -3682,7 +3680,11 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c case _N_none: default: - _Xregex_error(regex_constants::error_parse); +#if _ITERATOR_DEBUG_LEVEL != 0 + _STL_VERIFY(false, "internal data of regex node corrupted"); +#else // ^^^ _ITERATOR_DEBUG_LEVEL != 0 / _ITERATOR_DEBUG_LEVEL == 0 vvv + return false; +#endif // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ } if (_Failed) { diff --git a/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp b/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp index 8ba419dbd06..302200fc3ef 100644 --- a/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp +++ b/tests/std/tests/GH_002206_unreserved_names/test.compile.pass.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #define ISA_AVAILABILITY delete +#define error_parse delete #define nsec delete #define sec delete #define xtime delete diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index e7e10070ab3..c699d678eb5 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -547,6 +547,17 @@ void test_VSO_226914_word_boundaries() { aWordAny.should_search_fail("aa", match_not_bow | match_not_eow); } +void test_construction_from_nullptr_and_zero() { + { + regex re(nullptr, 0); + assert(re.mark_count() == 0); + } + { + wregex re(nullptr, 0); + assert(re.mark_count() == 0); + } +} + void test_gh_993() { // GH-993 regex::icase is not handled correctly for some input. { @@ -745,6 +756,7 @@ int main() { test_VSO_225160_match_bol_flag(); test_VSO_225160_match_eol_flag(); test_VSO_226914_word_boundaries(); + test_construction_from_nullptr_and_zero(); test_gh_993(); test_gh_4995(); test_gh_5058(); From 63fe8a22b502637811f038708357b721714a4072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 10:30:26 +0100 Subject: [PATCH 14/33] ``: Make negated character classes not match characters not included in the negated character class (#5214) Co-authored-by: Stephan T. Lavavej --- stl/inc/regex | 14 +++++++------- .../std/tests/VSO_0000000_regex_use/test.cpp | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 2b041163fa7..e2805021159 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1524,7 +1524,7 @@ public: void _Add_class(); void _Add_char_to_class(_Elem _Ch); void _Add_range2(_Elem, _Elem); - void _Add_named_class(_Regex_traits_base::char_class_type, bool = false); + void _Add_named_class(typename _RxTraits::char_class_type, bool); void _Add_equiv(_FwdIt, _FwdIt, _Difft); void _Add_coll(_FwdIt, _FwdIt, _Difft); _Node_base* _Begin_group(); @@ -1548,7 +1548,7 @@ private: bool _Beg_expr(_Node_base*) const; void _Add_char_to_bitmap(_Elem _Ch); void _Add_char_to_array(_Elem _Ch); - void _Add_elts(_Node_class<_Elem, _RxTraits>*, _Regex_traits_base::char_class_type, bool); + void _Add_elts(_Node_class<_Elem, _RxTraits>*, typename _RxTraits::char_class_type, bool); void _Char_to_elts(_FwdIt, _FwdIt, _Difft, _Sequence<_Elem>**); _Root_node* _Root; @@ -2935,7 +2935,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _E template void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( - _Node_class<_Elem, _RxTraits>* _Node, _Regex_traits_base::char_class_type _Cl, bool _Negate) { + _Node_class<_Elem, _RxTraits>* _Node, typename _RxTraits::char_class_type _Cl, bool _Negate) { // add characters in named class to set for (unsigned int _Ch = 0; _Ch < _Bmp_max; ++_Ch) { // add elements or their inverse bool _Matches = _Traits.isctype(static_cast<_Elem>(_Ch), _Cl); @@ -2950,12 +2950,12 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( } template -void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _Regex_traits_base::char_class_type _Cl, +void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _RxTraits::char_class_type _Cl, bool _Negate) { // add contents of named class to bracket expression _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current); _Add_elts(_Node, _Cl, _Negate); - if (_Bmp_max < static_cast(_STD _Max_limit<_Elem>())) { - _Node->_Classes = static_cast<_Regex_traits_base::char_class_type>(_Node->_Classes | _Cl); + if (_Bmp_max <= _STD _Max_limit() && !_Negate) { + _Node->_Classes = static_cast(_Node->_Classes | _Cl); } } @@ -4023,7 +4023,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Do_ex_class( _Error(regex_constants::error_ctype); } - _Nfa._Add_named_class(_Cls); + _Nfa._Add_named_class(_Cls, false); } else if (_End_arg == _Meta_equal) { // process = if (_Beg == _Pat) { _Error(regex_constants::error_collate); diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index c699d678eb5..0efb1979e40 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -730,6 +730,24 @@ void test_gh_5192() { } } +void test_gh_5214() { + // GH-5214 makes negated character class escapes not match characters not included in the negated character class + { + const test_wregex neg_word_regex(&g_regexTester, LR"([\W])"); + neg_word_regex.should_search_fail(L"\u0100"); // U+0100 LATIN CAPITAL LETTER A WITH MACRON + } + + { + const test_wregex neg_space_regex(&g_regexTester, LR"([\S])"); + neg_space_regex.should_search_fail(L"\u2028"); // U+2028 LINE SEPARATOR + } + + { + const test_wregex neg_digit_regex(&g_regexTester, LR"([\D])"); + neg_digit_regex.should_search_fail(L"\u0662"); // U+0662 ARABIC-INDIC DIGIT TWO + } +} + int main() { test_dev10_449367_case_insensitivity_should_work(); test_dev11_462743_regex_collate_should_not_disable_regex_icase(); @@ -763,6 +781,7 @@ int main() { test_gh_5160(); test_gh_5167(); test_gh_5192(); + test_gh_5214(); return g_regexTester.result(); } From 91a8d4f4e619317a3122fdbda239d941ee239aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Tue, 14 Jan 2025 10:36:22 +0100 Subject: [PATCH 15/33] Categorize some failing libcxx tests (#5231) Co-authored-by: Stephan T. Lavavej --- tests/libcxx/expected_results.txt | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 3329d34b8f1..dc60ee90278 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -36,12 +36,20 @@ std/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/param_ctor.pass.cpp # LLVM-113609: [libc++][test] Non-rebindable test_alloc in string.capacity/deallocate_size.pass.cpp std/strings/basic.string/string.capacity/deallocate_size.pass.cpp FAIL +# LLVM-116054: [libc++] vprint_[non]unicode(ostream &, string_view, Args&&...) should not pad the output +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL + # LLVM-119174: [libcxx][test] Silence nodiscard warnings for std::expected std/utilities/expected/expected.expected/monadic/and_then.pass.cpp FAIL std/utilities/expected/expected.expected/monadic/or_else.pass.cpp FAIL std/utilities/expected/expected.expected/monadic/transform.pass.cpp FAIL std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp FAIL +# LLVM-122638: [libc++][test] re.regex.construct/bad_backref.pass.cpp assumes non-standard extension to extended regular expressions +std/re/re.regex/re.regex.construct/bad_backref.pass.cpp 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 @@ -151,6 +159,9 @@ std/language.support/support.limits/support.limits.general/ranges.version.compil # libc++ is missing various DRs std/language.support/support.limits/support.limits.general/format.version.compile.pass.cpp FAIL +# libc++ doesn't implement LWG-2584 (LLVM-99976) +std/re/re.regex/re.regex.construct/bad_escape.pass.cpp FAIL + # libc++ doesn't implement LWG-3670 std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp FAIL @@ -240,8 +251,10 @@ std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/ctad. # *** MISSING LWG ISSUE RESOLUTIONS *** # LWG-2503 "multiline option should be added to syntax_option_type" +std/re/re.alg/re.alg.search/no_update_pos.pass.cpp FAIL std/re/re.const/re.matchflag/match_multiline.pass.cpp FAIL std/re/re.const/re.matchflag/match_not_eol.pass.cpp FAIL +std/re/re.const/re.synopt/syntax_option_type.pass.cpp FAIL # LWG-2532 "Satisfying a promise at thread exit" (Open) # WCFB02 implements the proposed resolution for this issue @@ -552,6 +565,12 @@ std/utilities/format/format.formatter/format.formatter.locking/enable_nonlocking std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp FAIL std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp FAIL +# We disagree on the syntax flags set by the default basic_regex constructor: we set 0, libc++ sets ECMAScript. +# Relates to LWG-3604. +std/re/re.regex/re.regex.construct/default.pass.cpp FAIL +std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp FAIL +std/re/re.regex/re.regex.swap/swap.pass.cpp FAIL + # *** LIKELY STL BUGS *** # Not analyzed, likely STL bugs. Various assertions. @@ -563,13 +582,6 @@ std/re/re.alg/re.alg.search/awk.pass.cpp FAIL std/re/re.alg/re.alg.search/basic.pass.cpp FAIL std/re/re.alg/re.alg.search/ecma.pass.cpp FAIL std/re/re.alg/re.alg.search/extended.pass.cpp FAIL -std/re/re.alg/re.alg.search/no_update_pos.pass.cpp FAIL -std/re/re.const/re.synopt/syntax_option_type.pass.cpp FAIL -std/re/re.regex/re.regex.construct/bad_backref.pass.cpp FAIL -std/re/re.regex/re.regex.construct/bad_escape.pass.cpp FAIL -std/re/re.regex/re.regex.construct/default.pass.cpp FAIL -std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp FAIL -std/re/re.regex/re.regex.swap/swap.pass.cpp FAIL std/re/re.traits/lookup_collatename.pass.cpp FAIL std/re/re.traits/transform_primary.pass.cpp FAIL @@ -1112,11 +1124,6 @@ std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical # Clang error: unknown attribute 'no_unique_address' ignored [-Werror,-Wunknown-attributes] std/ranges/ranges_robust_against_no_unique_address.pass.cpp FAIL -# Not analyzed. Runtime assertion, we appear to be ignoring stream width. -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp FAIL -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL -std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL - # Not analyzed. test_chrono_leap_second.h wants us to provide a vendor-specific version of # test_leap_second_create(), but it's unclear how to adapt their parameters to our implementation. std/time/time.zone/time.zone.leap/assign.copy.pass.cpp FAIL From 3c31602e0b7c05ed67e56182a11211ff731c2fab Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:38:39 +0800 Subject: [PATCH 16/33] ``: Detect some invalid contiguous ranges in `range_formatter` (#5187) Co-authored-by: Stephan T. Lavavej --- stl/inc/format | 6 +- tests/std/test.lst | 1 + .../env.lst | 4 + .../test.cpp | 113 ++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 tests/std/tests/P2286R8_text_formatting_range_string_death/env.lst create mode 100644 tests/std/tests/P2286R8_text_formatting_range_string_death/test.cpp diff --git a/stl/inc/format b/stl/inc/format index 6026f34202d..53b960dbdd6 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -3288,9 +3288,11 @@ void _Range_formatter_format_as_string(_Range&& _Rng, _FormatContext& _Ctx, cons if constexpr (_RANGES contiguous_range<_Range>) { const auto _Size = _STD _To_unsigned_like(_RANGES distance(_Rng)); - if (!_STD in_range(_Size)) [[unlikely]] { - _Throw_format_error("Formatted range is too long."); +#ifdef _DEBUG + if constexpr (sizeof(_Size) > sizeof(size_t)) { + _STL_VERIFY(_Size <= size_t{PTRDIFF_MAX}, "contiguous range has impossible size."); } +#endif // defined(_DEBUG) formatter, _CharT> _String_view_formatter; if (_Debug) { diff --git a/tests/std/test.lst b/tests/std/test.lst index 4e38b8fb265..7093936102a 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -638,6 +638,7 @@ tests\P2286R8_text_formatting_range_map tests\P2286R8_text_formatting_range_sequence tests\P2286R8_text_formatting_range_set tests\P2286R8_text_formatting_range_string +tests\P2286R8_text_formatting_range_string_death tests\P2286R8_text_formatting_tuple tests\P2286R8_text_formatting_tuple_disambiguation tests\P2286R8_text_formatting_vector_bool_reference diff --git a/tests/std/tests/P2286R8_text_formatting_range_string_death/env.lst b/tests/std/tests/P2286R8_text_formatting_range_string_death/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/P2286R8_text_formatting_range_string_death/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P2286R8_text_formatting_range_string_death/test.cpp b/tests/std/tests/P2286R8_text_formatting_range_string_death/test.cpp new file mode 100644 index 00000000000..bee4f6bc5a6 --- /dev/null +++ b/tests/std/tests/P2286R8_text_formatting_range_string_death/test.cpp @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; + +struct based_huge_iterator { + const char* base_; + _Signed128 offset_; + + using iterator_category = contiguous_iterator_tag; + using difference_type = _Signed128; + using value_type = char; + + const char& operator*() const noexcept { + return base_[static_cast(offset_)]; + } + + based_huge_iterator& operator++() noexcept { + ++offset_; + return *this; + } + based_huge_iterator operator++(int) noexcept { + auto old = *this; + ++*this; + return old; + } + + based_huge_iterator& operator--() noexcept { + --offset_; + return *this; + } + based_huge_iterator operator--(int) noexcept { + auto old = *this; + --*this; + return old; + } + + based_huge_iterator& operator+=(difference_type n) noexcept { + offset_ += n; + return *this; + } + + based_huge_iterator& operator-=(difference_type n) noexcept { + offset_ -= n; + return *this; + } + + const char* operator->() const noexcept { + return base_ + static_cast(offset_); + } + + const char& operator[](difference_type n) const noexcept { + return base_[static_cast(offset_ + n)]; + } + + friend based_huge_iterator operator+(based_huge_iterator i, difference_type n) noexcept { + return {i.base_, i.offset_ + n}; + } + friend based_huge_iterator operator+(difference_type n, based_huge_iterator i) noexcept { + return {i.base_, i.offset_ + n}; + } + + friend based_huge_iterator operator-(based_huge_iterator i, difference_type n) noexcept { + return {i.base_, i.offset_ - n}; + } + friend difference_type operator-(based_huge_iterator i, based_huge_iterator j) noexcept { + assert(i.base_ == j.base_); + return i.offset_ - j.offset_; + } + + friend auto operator<=>(const based_huge_iterator&, const based_huge_iterator&) = default; +}; + +struct based_huge_view : ranges::view_interface { + const char* base_; + _Signed128 size_; + + based_huge_iterator begin() const noexcept { + return {base_, 0}; + } + + based_huge_iterator end() const noexcept { + return {base_, size_}; + } +}; + +static_assert(ranges::contiguous_range); + +void test_case_invalid_range_size() { + based_huge_view v{.base_ = "", .size_ = static_cast(PTRDIFF_MAX) + 1}; + (void) format("{:s}", v); +} + +int main(int argc, char** argv) { + std_testing::death_test_executive exec; + +#ifdef _DEBUG + exec.add_death_tests({ + test_case_invalid_range_size, + }); +#endif // defined(_DEBUG) + + return exec.run(argc, argv); +} From 3a8f6c59b30e8c120944333c767d947f50435094 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:41:39 +0800 Subject: [PATCH 17/33] ``: Deprecate non-Standard `locale::empty()` (#5197) --- stl/inc/xlocale | 3 ++- stl/inc/yvals_core.h | 12 +++++++++++- stl/src/locale0.cpp | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index 40f3719d527..ed2f61f1c2d 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -400,7 +400,8 @@ public: static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL global(const locale&); // current locale - static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL empty(); // empty (transparent) locale + // TRANSITION, ABI: non-Standard empty() is preserved for binary compatibility + _DEPRECATE_LOCALE_EMPTY static _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL empty(); // empty (transparent) locale private: struct _Secret_locale_construct_tag { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 913e728b71a..bb52653bd42 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1517,7 +1517,17 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS #endif // ^^^ warning disabled ^^^ -// next warning number: STL4048 +#if !defined(_SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING) && !defined(_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS) +#define _DEPRECATE_LOCALE_EMPTY \ + [[deprecated( \ + "warning STL4048: locale::empty() is a non-Standard extension and will be removed in the future. A " \ + "default-constructed locale can be used instead. You can define _SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING or " \ + "_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS to suppress this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _DEPRECATE_LOCALE_EMPTY +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4049 // next error number: STL1006 diff --git a/stl/src/locale0.cpp b/stl/src/locale0.cpp index 032dbb2d982..81aae0ad22e 100644 --- a/stl/src/locale0.cpp +++ b/stl/src/locale0.cpp @@ -9,6 +9,8 @@ #undef _ENFORCE_ONLY_CORE_HEADERS // TRANSITION, should be a core header +#define _SILENCE_LOCALE_EMPTY_DEPRECATION_WARNING + #include #include #include From 6d5d462f691bcd0702229793695e6e74b1063669 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:44:12 +0800 Subject: [PATCH 18/33] Implement LWG-4144 Disallow `unique_ptr` (#5201) Co-authored-by: Stephan T. Lavavej --- stl/inc/memory | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stl/inc/memory b/stl/inc/memory index 864f44f90af..88b630d8ead 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3329,9 +3329,17 @@ template using _Unique_ptr_enable_default_t = enable_if_t>, is_default_constructible<_Dx2>>, int>; +template +constexpr bool _Can_form_pointer = false; +template +constexpr bool _Can_form_pointer<_Ty, void_t<_Ty*>> = true; + _EXPORT_STD template */> class unique_ptr { // non-copyable pointer to an object public: + static_assert(_Can_form_pointer<_Ty>, + "unique_ptr requires T* to be a valid type (N5001 [unique.ptr.single.general]/1)."); + using pointer = typename _Get_deleter_pointer_type<_Ty, remove_reference_t<_Dx>>::type; using element_type = _Ty; using deleter_type = _Dx; From a9861c95f21e64feacb78842a4f81e53c741bdeb Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:46:28 +0800 Subject: [PATCH 19/33] Make STL components not dependent on `is_trivial(_v)` (#5202) Co-authored-by: Stephan T. Lavavej --- stl/inc/__msvc_string_view.hpp | 7 +++-- stl/inc/execution | 3 +- stl/inc/filesystem | 11 ++------ stl/inc/memory | 6 ++-- stl/inc/type_traits | 6 ++-- stl/inc/xstring | 12 ++++---- .../tests/GH_000431_copy_move_family/test.cpp | 7 +++-- .../test.compile.pass.cpp | 19 +++++++------ .../P0009R18_mdspan_layout_left/test.cpp | 5 ++-- .../P0009R18_mdspan_layout_right/test.cpp | 5 ++-- .../P0009R18_mdspan_layout_stride/test.cpp | 5 ++-- .../std/tests/P0009R18_mdspan_mdspan/test.cpp | 3 +- tests/std/tests/P0323R12_expected/test.cpp | 3 +- .../tests/P0513R0_poisoning_the_hash/test.cpp | 2 +- .../P0896R4_P1614R2_comparisons/test.cpp | 3 +- .../test.compile.pass.cpp | 28 +++++++++++++------ .../P0896R4_ranges_range_machinery/test.cpp | 3 +- .../tests/P2322R6_ranges_alg_fold/test.cpp | 3 +- 18 files changed, 75 insertions(+), 56 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 57fc646177e..14198cbdf6b 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -1344,9 +1344,10 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer "Bad char_traits for basic_string_view; N4950 [string.view.template.general]/1 " "\"The program is ill-formed if traits::char_type is not the same type as charT.\""); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string_view must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string_view must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); using traits_type = _Traits; using value_type = _Elem; diff --git a/stl/inc/execution b/stl/inc/execution index 8f9ed7b5501..99801e6d75c 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -500,7 +500,8 @@ struct _Parallel_choose_max_chunk { template struct alignas(_Ty) alignas(size_t) alignas(_Atomic_counter_t) _Circular_buffer { // work stealing deque extent type - static_assert(is_trivial_v<_Ty>, "Work stealing deques work only with trivial operations"); + static_assert(is_trivially_copyable_v<_Ty> && is_trivially_default_constructible_v<_Ty>, + "Work stealing deques work only with trivial operations"); size_t _Log_size; _Atomic_counter_t _Ref_count; diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 8a20d566326..34562e576cb 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -352,19 +352,12 @@ namespace filesystem { inline constexpr _Is_slash_oper _Is_slash{}; - template - _NODISCARD _Ty _Unaligned_load(const void* _Ptr) { // load a _Ty from _Ptr - static_assert(is_trivial_v<_Ty>, "Unaligned loads require trivial types"); - _Ty _Tmp; - _CSTD memcpy(&_Tmp, _Ptr, sizeof(_Tmp)); - return _Tmp; - } - _NODISCARD inline bool _Is_drive_prefix(const wchar_t* const _First) { // test if _First points to a prefix of the form X: // pre: _First points to at least 2 wchar_t instances // pre: Little endian - auto _Value = _Unaligned_load(_First); + unsigned int _Value; + _CSTD memcpy(&_Value, _First, sizeof(_Value)); // load from possibly unaligned address _Value &= 0xFFFF'FFDFu; // transform lowercase drive letters into uppercase ones _Value -= (static_cast(L':') << (sizeof(wchar_t) * CHAR_BIT)) | L'A'; return _Value < 26; diff --git a/stl/inc/memory b/stl/inc/memory index 88b630d8ead..49d0e0af838 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -2246,7 +2246,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_guard { template void _Uninitialized_copy_multidimensional(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size]) { - if constexpr (is_trivial_v<_Ty>) { + using _Item = remove_all_extents_t<_Ty>; + if constexpr (conjunction_v, is_trivially_destructible<_Item>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_guard<_Ty> _Guard{_Out, 0}; @@ -2610,7 +2611,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_al_guard { template void _Uninitialized_copy_multidimensional_al(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size], _Alloc& _Al) { using _Item = remove_all_extents_t<_Ty>; - if constexpr (conjunction_v, _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { + if constexpr (conjunction_v, is_trivially_destructible<_Item>, + _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_al_guard<_Ty, _Alloc> _Guard{_Out, 0, _Al}; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 8edd5d4c62b..93d6422336d 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -2299,7 +2299,7 @@ _NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val, const unsigned char* c template _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First, const _Ty* const _Last) noexcept { // accumulate range [_First, _Last) into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Ty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Ty>, "Only trivially copyable types can be directly hashed."); const auto _Firstb = reinterpret_cast(_First); const auto _Lastb = reinterpret_cast(_Last); return _Fnv1a_append_bytes(_Val, _Firstb, static_cast(_Lastb - _Firstb)); @@ -2308,7 +2308,7 @@ _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First template _NODISCARD size_t _Fnv1a_append_value( const size_t _Val, const _Kty& _Keyval) noexcept { // accumulate _Keyval into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes(_Val, &reinterpret_cast(_Keyval), sizeof(_Kty)); } @@ -2320,7 +2320,7 @@ _NODISCARD size_t _Hash_representation(const _Kty& _Keyval) noexcept { // bitwis template _NODISCARD size_t _Hash_array_representation( const _Kty* const _First, const size_t _Count) noexcept { // bitwise hashes the representation of an array - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes( _FNV_offset_basis, reinterpret_cast(_First), _Count * sizeof(_Kty)); } diff --git a/stl/inc/xstring b/stl/inc/xstring index e39cb1871a3..55b5a67de10 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -538,9 +538,10 @@ private: "N4950 [string.require]/3 requires that the supplied " "char_traits character type match the string's character type."); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); public: using traits_type = _Traits; @@ -573,12 +574,13 @@ private: // _String_val::_Bx::_Ptr (type is pointer) // _String_val::_Mysize (type is size_type) // _String_val::_Myres (type is size_type) - // N4950 [strings.general]/1 says _Elem must be trivial standard-layout, so memcpy is safe. + // N5001 [strings.general]/1 says _Elem must be trivially copyable standard-layout, so memcpy is safe. // We need to ask if pointer is safe to memcpy. // size_type must be an unsigned integral type so memcpy is safe. // We also need to disable memcpy if the user has supplied _Traits, since // they can observe traits::assign and similar. - static constexpr bool _Can_memcpy_val = _Is_specialization_v<_Traits, char_traits> && is_trivial_v; + static constexpr bool _Can_memcpy_val = + _Is_specialization_v<_Traits, char_traits> && is_trivially_copyable_v; // This offset skips over the _Container_base members, if any static constexpr size_t _Memcpy_val_offset = _Size_after_ebco_v<_Container_base>; static constexpr size_t _Memcpy_val_size = sizeof(_Scary_val) - _Memcpy_val_offset; diff --git a/tests/std/tests/GH_000431_copy_move_family/test.cpp b/tests/std/tests/GH_000431_copy_move_family/test.cpp index 125792ea6e4..3527ebf0bb7 100644 --- a/tests/std/tests/GH_000431_copy_move_family/test.cpp +++ b/tests/std/tests/GH_000431_copy_move_family/test.cpp @@ -37,7 +37,8 @@ struct TrivialStruct { return i == right.i; } }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; @@ -49,7 +50,7 @@ struct TriviallyCopyableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -65,7 +66,7 @@ struct TriviallyMovableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); enum int_enum : int {}; enum char_enum : char {}; diff --git a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp index cac035a3e90..8041ee4127e 100644 --- a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp +++ b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp @@ -170,14 +170,15 @@ void test_iter_cat_for_containers() { struct TrivialStruct { int i; }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; TriviallyCopyableStruct(); }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -188,7 +189,7 @@ struct TriviallyMovableStruct { TriviallyMovableStruct& operator=(TriviallyMovableStruct&&) = default; }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyConstructibleStruct { int i; @@ -204,7 +205,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyAssignableStruct { int i; @@ -220,7 +221,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyConstructibleStruct { int i; @@ -236,7 +237,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyAssignableStruct { int i; @@ -253,7 +254,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveConstructibleStruct { int i; @@ -269,7 +270,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveAssignableStruct { int i; @@ -285,7 +286,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct EmptyBase {}; diff --git a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp index c48709d1875..d1bdbdfa72b 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_left::mapping; - // layout_left meets the layout mapping policy requirements and is a trivial type + // layout_left meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_left::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp index ef08dd7e9a9..75c685c3e92 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_right::mapping; - // layout_right meets the layout mapping policy requirements and is a trivial type + // layout_right meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_right::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 5f34b8c1541..033b68fc761 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -105,9 +105,10 @@ constexpr void do_check_members(const extents& ext, using Strides = array; using Mapping = layout_stride::mapping; - // layout_stride meets the layout mapping policy requirements and is a trivial type + // layout_stride meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_stride::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index c68533ccd0e..8a682080e90 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -337,7 +337,8 @@ struct TrivialAccessor { }; static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivial_v>); +static_assert(is_trivially_copyable_v>); +static_assert(is_trivially_default_constructible_v>); template class AccessorTemplate> constexpr void check_modeled_concepts_and_member_types() { diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index b964b554c8f..ba0e7f4d685 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -173,7 +173,8 @@ namespace test_unexpected { namespace test_unexpect { auto copy = unexpect; static_assert(is_same_v); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); static_assert(is_empty_v); } // namespace test_unexpect diff --git a/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp b/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp index acd3a8d11af..0625be2e3e4 100644 --- a/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp +++ b/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp @@ -52,7 +52,7 @@ constexpr bool standard_hash_enabled() { && is_trivially_move_constructible_v> // && is_trivially_copy_assignable_v> // && is_trivially_move_assignable_v> // - && is_trivial_v> // as a consequence of the above + && is_trivially_copyable_v> // && is_same_v::argument_type, T> // && is_same_v::result_type, size_t> // && (noexcept(hash{}(declval())) == NoExcept) // diff --git a/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp b/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp index f44a8d332a8..9582b548a25 100644 --- a/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp +++ b/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp @@ -52,7 +52,8 @@ constexpr bool is_trivially_constexpr() { // Not required, but likely portable nonetheless: STATIC_ASSERT(std::is_empty_v); - STATIC_ASSERT(std::is_trivial_v); + STATIC_ASSERT(std::is_trivially_copyable_v); + STATIC_ASSERT(std::is_trivially_default_constructible_v); STATIC_ASSERT(std::is_trivially_copy_constructible_v); STATIC_ASSERT(std::is_trivially_move_constructible_v); STATIC_ASSERT(std::is_trivially_copy_assignable_v); diff --git a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp index aa272fea61b..c2fe39556fb 100644 --- a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp +++ b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp @@ -547,7 +547,8 @@ namespace dangling_test { namespace result_test { using ranges::in_found_result, ranges::in_fun_result, ranges::in_in_result, ranges::in_out_result, ranges::in_in_out_result, ranges::in_out_out_result, ranges::min_max_result; - using std::is_aggregate_v, std::is_convertible_v, std::is_trivial_v; + using std::is_aggregate_v, std::is_convertible_v, std::is_trivially_copyable_v, + std::is_trivially_default_constructible_v; // Validate the result types are: // * aggregates @@ -559,14 +560,23 @@ namespace result_test { static_assert(is_aggregate_v>); static_assert(is_aggregate_v>); - // * trivial when parameter types are trivial - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); + // * trivially copyable when parameter types are trivially copyable + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + + // * trivially default constructible when parameter types are trivially default constructible + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); // * usable with structured bindings constexpr bool test_bindings_in_found_result() { diff --git a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp index 40d4d320f4f..fb4b4d6f98e 100644 --- a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp @@ -54,9 +54,10 @@ constexpr bool test_cpo(T const& obj) { // Not required, but likely portable nonetheless: static_assert(std::is_empty_v); - static_assert(std::is_trivial_v); + static_assert(std::is_trivially_copyable_v); static_assert(std::is_nothrow_destructible_v); static_assert(std::is_nothrow_default_constructible_v); + static_assert(std::is_trivially_default_constructible_v); static_assert(std::is_nothrow_copy_constructible_v); static_assert(std::is_trivially_copy_constructible_v); static_assert(std::is_nothrow_move_constructible_v); diff --git a/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp b/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp index ca5ce231773..72244709389 100644 --- a/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp +++ b/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp @@ -252,7 +252,8 @@ struct instantiator { constexpr bool test_in_value_result() { using ranges::in_value_result; static_assert(is_aggregate_v>); - static_assert(is_trivial_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_default_constructible_v>); in_value_result res = {nullptr, 6}; { // Validate binding From 313e1f47d2db276f18f72d7eb063643753cf5ed6 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:48:46 +0800 Subject: [PATCH 20/33] ``: Get rid of tricks for transparent overloads of hash containers (#5208) Co-authored-by: Stephan T. Lavavej --- stl/inc/hash_map | 7 +- stl/inc/hash_set | 7 +- stl/inc/xhash | 76 ++++++++++++++----- .../test.cpp | 30 ++++++++ 4 files changed, 97 insertions(+), 23 deletions(-) diff --git a/stl/inc/hash_map b/stl/inc/hash_map index b204ecba06f..6675ac79037 100644 --- a/stl/inc/hash_map +++ b/stl/inc/hash_map @@ -54,9 +54,10 @@ namespace stdext { template using _In_place_key_extractor = _STD _In_place_key_extract_map<_Kty, _Args...>; - template - using _Deduce_key = const _Kty&; - using key_equal = _Tr; + + using key_equal = _Tr; + + static constexpr bool _Has_transparent_overloads = false; #if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 template diff --git a/stl/inc/hash_set b/stl/inc/hash_set index 914a09c5586..4aeabd0177b 100644 --- a/stl/inc/hash_set +++ b/stl/inc/hash_set @@ -49,9 +49,10 @@ namespace stdext { template using _In_place_key_extractor = _STD _In_place_key_extract_set<_Kty, _Args...>; - template - using _Deduce_key = const _Kty&; - using key_equal = _Tr; + + using key_equal = _Tr; + + static constexpr bool _Has_transparent_overloads = false; #if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 template diff --git a/stl/inc/xhash b/stl/inc/xhash index 33854c4af0a..617138b038b 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -96,8 +96,7 @@ _STD_BEGIN template struct _Uhash_choose_transparency { // transparency selector for non-transparent hashed containers - template - using _Deduce_key = const _Kty&; + static constexpr bool _Has_transparent_overloads = false; #if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 template @@ -110,8 +109,7 @@ template requires _Is_transparent_v<_Hasher> && _Is_transparent_v<_Keyeq> struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq> { // transparency selector for transparent hashed containers - template - using _Deduce_key = const _Keyty&; + static constexpr bool _Has_transparent_overloads = true; template static constexpr bool _Supports_transparency = @@ -1225,25 +1223,41 @@ private: } public: - template - _NODISCARD iterator find(typename _Traits::template _Deduce_key<_Keyty> _Keyval) { + _NODISCARD iterator find(const key_type& _Keyval) { return _List._Make_iter(_Find(_Keyval, _Traitsobj(_Keyval))); } - template - _NODISCARD const_iterator find(typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD iterator find(const _KeyTy& _Keyval) { + return _List._Make_iter(_Find(_Keyval, _Traitsobj(_Keyval))); + } +#endif // _HAS_CXX20 + + _NODISCARD const_iterator find(const key_type& _Keyval) const { return _List._Make_const_iter(_Find(_Keyval, _Traitsobj(_Keyval))); } #if _HAS_CXX20 - template - _NODISCARD bool contains(_Traits::template _Deduce_key<_Keyty> _Keyval) const { + template + requires _Traits::_Has_transparent_overloads + _NODISCARD const_iterator find(const _KeyTy& _Keyval) const { + return _List._Make_const_iter(_Find(_Keyval, _Traitsobj(_Keyval))); + } + + _NODISCARD bool contains(const key_type& _Keyval) const { + return static_cast(_Find_last(_Keyval, _Traitsobj(_Keyval))._Duplicate); + } + + template + requires _Traits::_Has_transparent_overloads + _NODISCARD bool contains(const _KeyTy& _Keyval) const { return static_cast(_Find_last(_Keyval, _Traitsobj(_Keyval))._Duplicate); } #endif // _HAS_CXX20 - template - _NODISCARD size_type count(typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { + _NODISCARD size_type count(const key_type& _Keyval) const { const size_t _Hashval = _Traitsobj(_Keyval); if constexpr (_Multi) { return _Equal_range(_Keyval, _Hashval)._Distance; @@ -1252,6 +1266,19 @@ public: } } +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD size_type count(const _KeyTy& _Keyval) const { + const size_t _Hashval = _Traitsobj(_Keyval); + if constexpr (_Multi) { + return _Equal_range(_Keyval, _Hashval)._Distance; + } else { + return static_cast(_Find_last(_Keyval, _Hashval)._Duplicate); + } + } +#endif // _HAS_CXX20 + private: struct _Equal_range_result { _Unchecked_const_iterator _First; @@ -1307,18 +1334,33 @@ private: } public: - template - _NODISCARD pair equal_range(typename _Traits::template _Deduce_key<_Keyty> _Keyval) { + _NODISCARD pair equal_range(const key_type& _Keyval) { const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); return {_List._Make_iter(_Result._First._Ptr), _List._Make_iter(_Result._Last._Ptr)}; } - template - _NODISCARD pair equal_range( - typename _Traits::template _Deduce_key<_Keyty> _Keyval) const { +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD pair equal_range(const _KeyTy& _Keyval) { + const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); + return {_List._Make_iter(_Result._First._Ptr), _List._Make_iter(_Result._Last._Ptr)}; + } +#endif // _HAS_CXX20 + + _NODISCARD pair equal_range(const key_type& _Keyval) const { + const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); + return {_List._Make_const_iter(_Result._First._Ptr), _List._Make_const_iter(_Result._Last._Ptr)}; + } + +#if _HAS_CXX20 + template + requires _Traits::_Has_transparent_overloads + _NODISCARD pair equal_range(const _KeyTy& _Keyval) const { const auto _Result = _Equal_range(_Keyval, _Traitsobj(_Keyval)); return {_List._Make_const_iter(_Result._First._Ptr), _List._Make_const_iter(_Result._Last._Ptr)}; } +#endif // _HAS_CXX20 void swap(_Hash& _Right) noexcept(noexcept(_Traitsobj.swap(_Right._Traitsobj))) /* strengthened */ { if (this != _STD addressof(_Right)) { diff --git a/tests/std/tests/P0919R3_heterogeneous_unordered_lookup/test.cpp b/tests/std/tests/P0919R3_heterogeneous_unordered_lookup/test.cpp index ded59d4dce7..2fc85fe256d 100644 --- a/tests/std/tests/P0919R3_heterogeneous_unordered_lookup/test.cpp +++ b/tests/std/tests/P0919R3_heterogeneous_unordered_lookup/test.cpp @@ -272,6 +272,9 @@ void assert_unique() { emplace_test_strings(cRawToExtract); #endif // _HAS_CXX23 + // GH-5207 ": Some member functions of transparent hash containers fail to work with initializer lists" + typename Container::key_type testNotInStringListSrc(testNotInString.data(), testNotInString.size()); + // Test that transparent containers pass through the string_view; non-transparent containers // are only passed in here with string_view value_type, so they also don't allocate. [[maybe_unused]] prohibit_allocations prohibitor(true); @@ -281,6 +284,18 @@ void assert_unique() { assert(c.count(testNotInString) == 0); assert_range_empty(c.equal_range(testNotInString)); + assert(c.find({testNotInStringListSrc}) == c.end()); + assert(c.contains({testNotInStringListSrc}) == false); + assert(c.count({testNotInStringListSrc}) == 0); + assert_range_empty(c.equal_range({testNotInStringListSrc})); + + // Test non-const overloads. + assert(cRaw.find(testNotInString) == cRaw.end()); + assert_range_empty(cRaw.equal_range(testNotInString)); + + assert(cRaw.find({testNotInStringListSrc}) == cRaw.end()); + assert_range_empty(cRaw.equal_range({testNotInStringListSrc})); + for (const auto& example : testStrings) { const auto target = c.find(example); assert(target != c.end()); @@ -328,6 +343,9 @@ void assert_multi() { #endif // _HAS_CXX23 } + // GH-5207 ": Some member functions of transparent hash containers fail to work with initializer lists" + typename Container::key_type testNotInStringListSrc(testNotInString.data(), testNotInString.size()); + // Test that transparent containers pass through the string_view; non-transparent containers // are only passed in here with string_view value_type, so they also don't allocate. [[maybe_unused]] prohibit_allocations prohibitor(true); @@ -337,6 +355,18 @@ void assert_multi() { assert(c.count(testNotInString) == 0); assert_range_empty(c.equal_range(testNotInString)); + assert(c.find({testNotInStringListSrc}) == c.end()); + assert(c.contains({testNotInStringListSrc}) == false); + assert(c.count({testNotInStringListSrc}) == 0); + assert_range_empty(c.equal_range({testNotInStringListSrc})); + + // Test non-const overloads. + assert(cRaw.find(testNotInString) == cRaw.end()); + assert_range_empty(cRaw.equal_range(testNotInString)); + + assert(cRaw.find({testNotInStringListSrc}) == cRaw.end()); + assert_range_empty(cRaw.equal_range({testNotInStringListSrc})); + for (const auto& example : testStrings) { const auto target = c.find(example); assert(target != c.end()); From 4119eb8436e2a084d8364509fcec3ee643e6d220 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:52:40 +0800 Subject: [PATCH 21/33] Implement P3323R1 `Forbid atomic`, Specify `atomic_ref` (#5213) Co-authored-by: Stephan T. Lavavej --- stl/inc/atomic | 261 ++++++++++++------ stl/inc/yvals_core.h | 4 + tests/libcxx/expected_results.txt | 3 + tests/std/tests/P0019R8_atomic_ref/test.cpp | 289 +++++++++++++++++--- 4 files changed, 425 insertions(+), 132 deletions(-) diff --git a/stl/inc/atomic b/stl/inc/atomic index 9f4da0a47e3..e42a4033c90 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -468,12 +468,13 @@ struct _Atomic_storage; template void _Atomic_wait_direct( const _Atomic_storage<_Ty>* const _This, _Value_type _Expected_bytes, const memory_order _Order) noexcept { - const auto _Storage_ptr = _STD addressof(_This->_Storage); + const auto _Storage_ptr = + const_cast(static_cast(_STD addressof(_This->_Storage))); for (;;) { const _Value_type _Observed_bytes = _STD _Atomic_reinterpret_as<_Value_type>(_This->load(_Order)); if (_Expected_bytes != _Observed_bytes) { #if _CMPXCHG_MASK_OUT_PADDING_BITS - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; if constexpr (_Might_have_non_value_bits<_TVal>) { _Storage_for<_TVal> _Mask{_Form_mask}; const _Value_type _Mask_val = _STD _Atomic_reinterpret_as<_Value_type>(_Mask._Ref()); @@ -581,7 +582,7 @@ struct _Atomic_storage { // Provides operations common to all specializations of std::atomic, load, store, exchange, and CAS. // Locking version used when hardware has no atomic operations for sizeof(_Ty). - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; using _Guard = _Atomic_lock_guard::_Spinlock>; _Atomic_storage() = default; @@ -713,7 +714,7 @@ public: template struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -801,11 +802,13 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -814,7 +817,7 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics template struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -901,11 +904,13 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -914,7 +919,7 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics template struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -1001,11 +1006,13 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1014,7 +1021,7 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics template struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics - using _TVal = remove_reference_t<_Ty>; + using _TVal = _Remove_cvref_t<_Ty>; _Atomic_storage() = default; @@ -1120,11 +1127,13 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_direct(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_direct(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_direct(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1135,7 +1144,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics template struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics // TRANSITION, ABI: replace '_Ty&' with '_Ty' in this specialization - using _TVal = remove_reference_t<_Ty&>; + using _TVal = _Remove_cvref_t<_Ty&>; _Atomic_storage() = default; @@ -1252,8 +1261,8 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics &_Expected_temp._Low); #else // ^^^ _M_ARM64, _M_ARM64EC / _M_X64 vvv (void) _Order; - _Result = _InterlockedCompareExchange128( - &reinterpret_cast(_Storage), _Desired_bytes._High, _Desired_bytes._Low, &_Expected_temp._Low); + _Result = _InterlockedCompareExchange128(&reinterpret_cast(_Storage), _Desired_bytes._High, + _Desired_bytes._Low, &_Expected_temp._Low); #endif // ^^^ _M_X64 ^^^ if (_Result == 0) { _CSTD memcpy(_STD addressof(_Expected), &_Expected_temp, sizeof(_TVal)); @@ -1264,7 +1273,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics #if _HAS_CXX20 void wait(_TVal _Expected, memory_order _Order = memory_order_seq_cst) const noexcept { - const auto _Storage_ptr = _STD addressof(_Storage); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); const auto _Expected_ptr = _STD addressof(_Expected); _Int128 _Expected_bytes = reinterpret_cast(_Expected); @@ -1294,11 +1303,13 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics } void notify_one() noexcept { - ::__std_atomic_notify_one_indirect(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_one_indirect(_Storage_ptr); } void notify_all() noexcept { - ::__std_atomic_notify_all_indirect(_STD addressof(_Storage)); + const auto _Storage_ptr = const_cast(static_cast(_STD addressof(_Storage))); + ::__std_atomic_notify_all_indirect(_Storage_ptr); } #endif // _HAS_CXX20 @@ -1615,9 +1626,18 @@ constexpr bool _Deprecate_non_lock_free_volatile = true; template _CXX20_DEPRECATE_VOLATILE constexpr bool _Deprecate_non_lock_free_volatile<_Ty, false> = true; +#if _HAS_CXX20 +#define _REQUIRES_CLAUSE(...) requires (__VA_ARGS__) +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define _REQUIRES_CLAUSE(...) +#endif // ^^^ !_HAS_CXX20 ^^^ + template struct _Atomic_integral_facade : _Atomic_integral<_Ty> { // provides operator overloads and other support for atomic integral specializations + _STL_INTERNAL_STATIC_ASSERT(!is_const_v<_Ty>); + _STL_INTERNAL_STATIC_ASSERT(!is_volatile_v<_Ty>); + using _Base = _Atomic_integral<_Ty>; using difference_type = _Ty; @@ -1747,88 +1767,89 @@ template struct _Atomic_integral_facade<_Ty&> : _Atomic_integral<_Ty&> { // provides operator overloads and other support for atomic integral specializations using _Base = _Atomic_integral<_Ty&>; - using difference_type = _Ty; + using difference_type = remove_cv_t<_Ty>; + using typename _Base::_TVal; using _Base::_Base; - _NODISCARD static _Ty _Negate(const _Ty _Value) noexcept { // returns two's complement negated value of _Value - return static_cast<_Ty>(0U - static_cast>(_Value)); + _NODISCARD static _TVal _Negate(const _TVal _Value) noexcept { // returns two's complement negated value of _Value + return static_cast<_TVal>(0U - static_cast>(_Value)); } - _Ty fetch_add(const _Ty _Operand) const noexcept { + _TVal fetch_add(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_add(_Operand); } - _Ty fetch_add(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_add(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_add(_Operand, _Order); } - _Ty fetch_sub(const _Ty _Operand) const noexcept { + _TVal fetch_sub(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Negate(_Operand)); } - _Ty fetch_sub(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_sub(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Negate(_Operand), _Order); } - _Ty operator++(int) const noexcept { + _TVal operator++(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++(0); } - _Ty operator++() const noexcept { + _TVal operator++() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++(); } - _Ty operator--(int) const noexcept { + _TVal operator--(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--(0); } - _Ty operator--() const noexcept { + _TVal operator--() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--(); } - _Ty operator+=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_add(_Operand) + _Operand); + _TVal operator+=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_add(_Operand) + _Operand); } - _Ty operator-=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_sub(_Operand) - _Operand); + _TVal operator-=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_sub(_Operand) - _Operand); } - _Ty fetch_and(const _Ty _Operand) const noexcept { + _TVal fetch_and(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_and(_Operand); } - _Ty fetch_and(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_and(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_and(_Operand, _Order); } - _Ty fetch_or(const _Ty _Operand) const noexcept { + _TVal fetch_or(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_or(_Operand); } - _Ty fetch_or(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_or(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_or(_Operand, _Order); } - _Ty fetch_xor(const _Ty _Operand) const noexcept { + _TVal fetch_xor(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_xor(_Operand); } - _Ty fetch_xor(const _Ty _Operand, const memory_order _Order) const noexcept { + _TVal fetch_xor(const _TVal _Operand, const memory_order _Order) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return const_cast<_Atomic_integral_facade*>(this)->_Base::fetch_xor(_Operand, _Order); } - _Ty operator&=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_and(_Operand) & _Operand); + _TVal operator&=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_and(_Operand) & _Operand); } - _Ty operator|=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_or(_Operand) | _Operand); + _TVal operator|=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_or(_Operand) | _Operand); } - _Ty operator^=(const _Ty _Operand) const noexcept { - return static_cast<_Ty>(fetch_xor(_Operand) ^ _Operand); + _TVal operator^=(const _TVal _Operand) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { + return static_cast<_TVal>(fetch_xor(_Operand) ^ _Operand); } }; @@ -1836,6 +1857,9 @@ struct _Atomic_integral_facade<_Ty&> : _Atomic_integral<_Ty&> { template struct _Atomic_floating : _Atomic_storage<_Ty> { // provides atomic floating-point operations + _STL_INTERNAL_STATIC_ASSERT(!is_const_v<_Ty>); + _STL_INTERNAL_STATIC_ASSERT(!is_volatile_v<_Ty>); + using _Base = _Atomic_storage<_Ty>; using difference_type = _Ty; @@ -1891,12 +1915,15 @@ template struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { // provides atomic floating-point operations using _Base = _Atomic_storage<_Ty&>; - using difference_type = _Ty; + using difference_type = remove_cv_t<_Ty>; + using typename _Base::_TVal; using _Base::_Base; - _Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept { - _Ty _Temp{this->load(memory_order_relaxed)}; + _TVal fetch_add(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept + requires (!is_const_v<_Ty>) + { + _TVal _Temp{this->load(memory_order_relaxed)}; while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp, _Temp + _Operand, _Order)) { // keep trying } @@ -1904,8 +1931,10 @@ struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { return _Temp; } - _Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept { - _Ty _Temp{this->load(memory_order_relaxed)}; + _TVal fetch_sub(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept + requires (!is_const_v<_Ty>) + { + _TVal _Temp{this->load(memory_order_relaxed)}; while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp, _Temp - _Operand, _Order)) { // keep trying } @@ -1913,11 +1942,15 @@ struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&> { return _Temp; } - _Ty operator+=(const _Ty _Operand) const noexcept { + _TVal operator+=(const _TVal _Operand) const noexcept + requires (!is_const_v<_Ty>) + { return fetch_add(_Operand) + _Operand; } - _Ty operator-=(const _Ty _Operand) const noexcept { + _TVal operator-=(const _TVal _Operand) const noexcept + requires (!is_const_v<_Ty>) + { return fetch_sub(_Operand) - _Operand; } }; @@ -2023,10 +2056,12 @@ template struct _Atomic_pointer<_Ty&> : _Atomic_storage<_Ty&> { using _Base = _Atomic_storage<_Ty&>; using difference_type = ptrdiff_t; + using typename _Base::_TVal; using _Base::_Base; - _Ty fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) const noexcept { + _TVal fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) const noexcept + _REQUIRES_CLAUSE(!is_const_v<_Ty>) { const ptrdiff_t _Shift_bytes = static_cast(static_cast(_Diff) * sizeof(remove_pointer_t<_Ty>)); ptrdiff_t _Result; @@ -2037,42 +2072,45 @@ struct _Atomic_pointer<_Ty&> : _Atomic_storage<_Ty&> { _ATOMIC_CHOOSE_INTRINSIC(static_cast(_Order), _Result, _InterlockedExchangeAdd64, _STD _Atomic_address_as(this->_Storage), _Shift_bytes); #endif // ^^^ 64 bits ^^^ - return reinterpret_cast<_Ty>(_Result); + return reinterpret_cast<_TVal>(_Result); } - _Ty fetch_sub(const ptrdiff_t _Diff) const noexcept { + _TVal fetch_sub(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff))); } - _Ty fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) const noexcept { + _TVal fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) const noexcept + _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff)), _Order); } - _Ty operator++(int) const noexcept { + _TVal operator++(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(1); } - _Ty operator++() const noexcept { + _TVal operator++() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(1) + 1; } - _Ty operator--(int) const noexcept { + _TVal operator--(int) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(-1); } - _Ty operator--() const noexcept { + _TVal operator--() const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(-1) - 1; } - _Ty operator+=(const ptrdiff_t _Diff) const noexcept { + _TVal operator+=(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(_Diff) + _Diff; } - _Ty operator-=(const ptrdiff_t _Diff) const noexcept { + _TVal operator-=(const ptrdiff_t _Diff) const noexcept _REQUIRES_CLAUSE(!is_const_v<_Ty>) { return fetch_add(static_cast(0 - static_cast(_Diff))) - _Diff; } }; +#undef _REQUIRES_CLAUSE + template struct _Atomic_nonobject_pointer : _Atomic_storage<_Ty> { using _Base = _Atomic_storage<_Ty>; @@ -2081,15 +2119,22 @@ struct _Atomic_nonobject_pointer : _Atomic_storage<_Ty> { using _Base::_Base; }; +template +struct _Atomic_nonobject_pointer<_Ty&> : _Atomic_storage<_Ty&> { + using _Base = _Atomic_storage<_Ty&>; + + using _Base::_Base; +}; + #define ATOMIC_VAR_INIT(_Value) {_Value} template using _Choose_atomic_base2_t = - typename _Select && !is_same_v>::template _Apply<_Atomic_integral_facade<_Ty>, - typename _Select>::template _Apply< - typename _Select>>::template _Apply<_Atomic_pointer<_Ty>, - _Atomic_nonobject_pointer<_Ty>>, - _Atomic_storage<_Ty>>>; + typename _Select && !is_same_v>>::template _Apply< + _Atomic_integral_facade<_Ty>, typename _Select>::template _Apply< + typename _Select>>::template _Apply< + _Atomic_pointer<_Ty>, _Atomic_nonobject_pointer<_Ty>>, + _Atomic_storage<_Ty>>>; #if _HAS_CXX20 template @@ -2106,10 +2151,13 @@ private: using _Base = _Choose_atomic_base_t<_Ty>; public: - static_assert(is_trivially_copyable_v<_Ty> && is_copy_constructible_v<_Ty> && is_move_constructible_v<_Ty> - && is_copy_assignable_v<_Ty> && is_move_assignable_v<_Ty>, - "atomic requires T to be trivially copyable, copy constructible, move constructible, copy assignable, " - "and move assignable."); + static_assert(is_trivially_copyable_v<_Ty>, "atomic requires T to be trivially copyable."); + static_assert(is_copy_constructible_v<_Ty>, "atomic requires T to be copy constructible."); + static_assert(is_move_constructible_v<_Ty>, "atomic requires T to be move constructible."); + static_assert(is_copy_assignable_v<_Ty>, "atomic requires T to be copy assignable."); + static_assert(is_move_assignable_v<_Ty>, "atomic requires T to be move assignable."); + static_assert(!is_const_v<_Ty>, "atomic requires T to be non-const."); + static_assert(!is_volatile_v<_Ty>, "atomic requires T to be non-volatile."); using value_type = _Ty; @@ -2276,7 +2324,7 @@ private: public: static_assert(is_trivially_copyable_v<_Ty>, "atomic_ref requires T to be trivially copyable."); - using value_type = _Ty; + using value_type = remove_cv_t<_Ty>; explicit atomic_ref(_Ty& _Value) noexcept /* strengthened */ : _Base(_Value) { if constexpr (is_always_lock_free) { @@ -2295,66 +2343,97 @@ public: static constexpr size_t required_alignment = is_always_lock_free ? sizeof(_Ty) : alignof(_Ty); + static_assert(is_always_lock_free || !is_volatile_v<_Ty>, + "atomic_ref requires T to be non-volatile when it is not always lock-free."); + _NODISCARD bool is_lock_free() const noexcept { return is_always_lock_free; } - void store(const _Ty _Value) const noexcept { + void store(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::store(_Value); } - void store(const _Ty _Value, const memory_order _Order) const noexcept { + void store(const value_type _Value, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::store(_Value, _Order); } - _Ty operator=(const _Ty _Value) const noexcept { + value_type operator=(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { store(_Value); return _Value; } - _Ty exchange(const _Ty _Value) const noexcept { + value_type exchange(const value_type _Value) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::exchange(_Value); } - _Ty exchange(const _Ty _Value, const memory_order _Order) const noexcept { + value_type exchange(const value_type _Value, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::exchange(_Value, _Order); } - bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired) const noexcept { + bool compare_exchange_strong(value_type& _Expected, const value_type _Desired) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::compare_exchange_strong(_Expected, _Desired); } - bool compare_exchange_strong(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) const noexcept { + bool compare_exchange_strong( + value_type& _Expected, const value_type _Desired, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return const_cast(this)->_Base::compare_exchange_strong(_Expected, _Desired, _Order); } - bool compare_exchange_strong( - _Ty& _Expected, const _Ty _Desired, const memory_order _Success, const memory_order _Failure) const noexcept { + bool compare_exchange_strong(value_type& _Expected, const value_type _Desired, const memory_order _Success, + const memory_order _Failure) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Combine_cas_memory_orders(_Success, _Failure)); } - bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired) const noexcept { + bool compare_exchange_weak(value_type& _Expected, const value_type _Desired) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired); } - bool compare_exchange_weak(_Ty& _Expected, const _Ty _Desired, const memory_order _Order) const noexcept { + bool compare_exchange_weak( + value_type& _Expected, const value_type _Desired, const memory_order _Order) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Order); } - bool compare_exchange_weak( - _Ty& _Expected, const _Ty _Desired, const memory_order _Success, const memory_order _Failure) const noexcept { + bool compare_exchange_weak(value_type& _Expected, const value_type _Desired, const memory_order _Success, + const memory_order _Failure) const noexcept + requires (!is_const_v<_Ty>) + { return compare_exchange_strong(_Expected, _Desired, _Combine_cas_memory_orders(_Success, _Failure)); } - operator _Ty() const noexcept { + operator value_type() const noexcept { return this->load(); } - void notify_one() const noexcept { + void notify_one() const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::notify_one(); } - void notify_all() const noexcept { + void notify_all() const noexcept + requires (!is_const_v<_Ty>) + { const_cast(this)->_Base::notify_all(); } diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index bb52653bd42..01c8c4187ce 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -80,6 +80,8 @@ // (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only) // P2937R0 Freestanding Library: Remove strtok // P2968R2 Make std::ignore A First-Class Object +// P3323R1 Forbid atomic, Specify atomic_ref +// (for atomic) // _HAS_CXX17 directly controls: // P0005R4 not_fn() @@ -315,6 +317,8 @@ // P2909R4 Fix Formatting Of Code Units As Integers // P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts // P3136R1 Retiring Niebloids +// P3323R1 Forbid atomic, Specify atomic_ref +// (for atomic_ref) // _HAS_CXX20 indirectly controls: // P0619R4 Removing C++17-Deprecated Features diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index dc60ee90278..824dd2f7314 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -134,6 +134,9 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil # libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok" std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL +# libc++ has not implemented P3323R1: "Forbid atomic, Specify atomic_ref" +std/atomics/atomics.ref/member_types.compile.pass.cpp FAIL + # Various bogosity (LLVM-D141004), warning C6011: Dereferencing NULL pointer # Note: The :1 (ASan) configuration doesn't run static analysis. std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp:0 FAIL diff --git a/tests/std/tests/P0019R8_atomic_ref/test.cpp b/tests/std/tests/P0019R8_atomic_ref/test.cpp index 8edf08cfd9e..47f42a78be0 100644 --- a/tests/std/tests/P0019R8_atomic_ref/test.cpp +++ b/tests/std/tests/P0019R8_atomic_ref/test.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -34,50 +35,256 @@ struct int128 { } }; -// Also test GH-4688 ": atomic_ref and atomic lack difference_type" +// Also test constraints and conditional existence of difference_type specified by +// P3323R1 "Forbid atomic, Specify atomic_ref". + +template +void test_atomic_ref_constraints_single() { // COMPILE-ONLY + using TD = std::remove_cv_t; + using AR = std::atomic_ref; + + static_assert(std::is_same_v); + static_assert(requires(const AR& r, TD v, std::memory_order ord) { + r.operator TD(); + { r.load() } -> std::same_as; + { r.load(ord) } -> std::same_as; + { r.wait(v) } -> std::same_as; + { r.wait(v, ord) } -> std::same_as; + }); + { + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, std::memory_order ord) { +#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-2343282 + (void) r.operator TD(); +#else // ^^^ no workaround / workaround vvv + [[maybe_unused]] TD td = r; +#endif // ^^^ workaround ^^^ + (void) r.load(); + (void) r.load(ord); + r.wait(v); + r.wait(v, ord); + }; + } + + if constexpr (!std::is_const_v) { + static_assert(requires(const AR& r, TD v, TD& vx, std::memory_order ord1, std::memory_order ord2) { + { r.store(v) } -> std::same_as; + { r.store(v, ord1) } -> std::same_as; + { r = v } -> std::same_as; + { r.exchange(v) } -> std::same_as; + { r.exchange(v, ord1) } -> std::same_as; + { r.compare_exchange_weak(vx, v) } -> std::same_as; + { r.compare_exchange_weak(vx, v, ord1) } -> std::same_as; + { r.compare_exchange_weak(vx, v, ord1, ord2) } -> std::same_as; + { r.compare_exchange_strong(vx, v) } -> std::same_as; + { r.compare_exchange_strong(vx, v, ord1) } -> std::same_as; + { r.compare_exchange_strong(vx, v, ord1, ord2) } -> std::same_as; + { r.notify_one() } -> std::same_as; + { r.notify_all() } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, TD& vx, std::memory_order ord1, + std::memory_order ord2) { + r.store(v); + r.store(v, ord1); + (void) (r = v); + (void) r.exchange(v); + (void) r.exchange(v, ord1); + (void) r.compare_exchange_weak(vx, v); + (void) r.compare_exchange_weak(vx, v, ord1); + (void) r.compare_exchange_weak(vx, v, ord1, ord2); + (void) r.compare_exchange_strong(vx, v); + (void) r.compare_exchange_strong(vx, v, ord1); + (void) r.compare_exchange_strong(vx, v, ord1, ord2); + r.notify_one(); + r.notify_all(); + }; + } else { + static_assert(!requires(const AR& r, TD v) { r.store(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.store(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r = v; }); + static_assert(!requires(const AR& r, TD v) { r.exchange(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.exchange(v, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2) { r.compare_exchange_weak(v1, v2); }); + static_assert( + !requires(const AR& r, TD& v1, TD v2, std::memory_order ord) { r.compare_exchange_weak(v1, v2, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2, std::memory_order ord1, std::memory_order ord2) { + r.compare_exchange_weak(v1, v2, ord1, ord2); + }); + static_assert(!requires(const AR& r, TD& v1, TD v2) { r.compare_exchange_strong(v1, v2); }); + static_assert( + !requires(const AR& r, TD& v1, TD v2, std::memory_order ord) { r.compare_exchange_strong(v1, v2, ord); }); + static_assert(!requires(const AR& r, TD& v1, TD v2, std::memory_order ord1, std::memory_order ord2) { + r.compare_exchange_strong(v1, v2, ord1, ord2); + }); + static_assert(!requires(const AR& r) { r.notify_one(); }); + static_assert(!requires(const AR& r) { r.notify_all(); }); + } + + constexpr bool has_difference_type = (std::is_arithmetic_v && !std::is_same_v) + || (std::is_pointer_v && std::is_object_v>); + + if constexpr (has_difference_type) { + if constexpr (std::is_arithmetic_v) { + static_assert(std::is_same_v); + } else { + static_assert(std::is_same_v); + } + } else { + static_assert(!requires { typename AR::difference_type; }); + } + + if constexpr (has_difference_type && !std::is_const_v) { + static_assert(requires(const AR& r, AR::difference_type d, std::memory_order ord) { + { r.fetch_add(d) } -> std::same_as; + { r.fetch_add(d, ord) } -> std::same_as; + { r.fetch_sub(d) } -> std::same_as; + { r.fetch_sub(d, ord) } -> std::same_as; + { r += d } -> std::same_as; + { r -= d } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, AR::difference_type d, std::memory_order ord) { + (void) r.fetch_add(d); + (void) r.fetch_add(d, ord); + (void) r.fetch_sub(d); + (void) r.fetch_sub(d, ord); + (void) (r += d); + (void) (r -= d); + }; + } else { + static_assert(!requires(const AR& r, AR::difference_type d) { r.fetch_add(d); }); + static_assert(!requires(const AR& r, AR::difference_type d, std::memory_order ord) { r.fetch_add(d, ord); }); + static_assert(!requires(const AR& r, AR::difference_type d) { r.fetch_sub(d); }); + static_assert(!requires(const AR& r, AR::difference_type d, std::memory_order ord) { r.fetch_sub(d, ord); }); + static_assert(!requires(const AR& r, AR::difference_type d) { r += d; }); + static_assert(!requires(const AR& r, AR::difference_type d) { r -= d; }); + } + + if constexpr (has_difference_type && !std::is_floating_point_v && !std::is_const_v) { + static_assert(requires(const AR& r) { + { ++r } -> std::same_as; + { r++ } -> std::same_as; + { --r } -> std::same_as; + { r-- } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r) { + (void) ++r; + (void) r++; + (void) --r; + (void) r--; + }; + } else { + static_assert(!requires(const AR& r) { ++r; }); + static_assert(!requires(const AR& r) { r++; }); + static_assert(!requires(const AR& r) { --r; }); + static_assert(!requires(const AR& r) { r--; }); + } + + if constexpr (std::is_integral_v && !std::is_same_v && !std::is_const_v) { + static_assert(requires(const AR& r, TD v, std::memory_order ord) { + { r.fetch_and(v) } -> std::same_as; + { r.fetch_and(v, ord) } -> std::same_as; + { r.fetch_or(v) } -> std::same_as; + { r.fetch_or(v, ord) } -> std::same_as; + { r.fetch_xor(v) } -> std::same_as; + { r.fetch_xor(v, ord) } -> std::same_as; + { r &= v } -> std::same_as; + { r |= v } -> std::same_as; + { r ^= v } -> std::same_as; + }); + + [[maybe_unused]] auto instantiator = [](const AR& r, TD v, std::memory_order ord) { + (void) r.fetch_and(v); + (void) r.fetch_and(v, ord); + (void) r.fetch_or(v); + (void) r.fetch_or(v, ord); + (void) r.fetch_xor(v); + (void) r.fetch_xor(v, ord); + (void) (r &= v); + (void) (r |= v); + (void) (r ^= v); + }; + } else { + static_assert(!requires(const AR& r, TD v) { r.fetch_and(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_and(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r.fetch_or(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_or(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r.fetch_xor(v); }); + static_assert(!requires(const AR& r, TD v, std::memory_order ord) { r.fetch_xor(v, ord); }); + static_assert(!requires(const AR& r, TD v) { r &= v; }); + static_assert(!requires(const AR& r, TD v) { r |= v; }); + static_assert(!requires(const AR& r, TD v) { r ^= v; }); + } +} + template -constexpr bool atomic_ref_has_member_difference_type = requires { typename std::atomic_ref::difference_type; }; - -static_assert(std::is_same_v::difference_type, signed char>); -static_assert(std::is_same_v::difference_type, short>); -static_assert(std::is_same_v::difference_type, int>); -static_assert(std::is_same_v::difference_type, long>); -static_assert(std::is_same_v::difference_type, long long>); -static_assert(std::is_same_v::difference_type, unsigned char>); -static_assert(std::is_same_v::difference_type, unsigned short>); -static_assert(std::is_same_v::difference_type, unsigned int>); -static_assert(std::is_same_v::difference_type, unsigned long>); -static_assert(std::is_same_v::difference_type, unsigned long long>); -static_assert(std::is_same_v::difference_type, char>); +void test_atomic_ref_constraints_cv() { // COMPILE-ONLY + static_assert(!std::is_const_v && !std::is_volatile_v); + test_atomic_ref_constraints_single(); + test_atomic_ref_constraints_single(); + if constexpr (std::atomic_ref::is_always_lock_free) { + test_atomic_ref_constraints_single(); + test_atomic_ref_constraints_single(); + } +} + +void test_atomic_ref_constraints() { // COMPILE-ONLY + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); #ifdef __cpp_char8_t -static_assert(std::is_same_v::difference_type, char8_t>); + test_atomic_ref_constraints_cv(); #endif // defined(__cpp_char8_t) -static_assert(std::is_same_v::difference_type, char16_t>); -static_assert(std::is_same_v::difference_type, char32_t>); -static_assert(std::is_same_v::difference_type, wchar_t>); - -static_assert(std::is_same_v::difference_type, float>); -static_assert(std::is_same_v::difference_type, double>); -static_assert(std::is_same_v::difference_type, long double>); - -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); - -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); -static_assert(std::is_same_v::difference_type, std::ptrdiff_t>); - -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); -static_assert(!atomic_ref_has_member_difference_type); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + + test_atomic_ref_constraints_cv(); + test_atomic_ref_constraints_cv(); +} // code reuse of ../P1135R6_atomic_flag_test/test.cpp From ba284eb85db2910bcdd7c871414f0dc7d8b921b4 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:55:08 +0800 Subject: [PATCH 22/33] Implement LWG-4119 `generator::promise_type::yield_value(ranges::elements_of)`'s nested `generator` may be ill-formed (#5220) Co-authored-by: Stephan T. Lavavej --- stl/inc/generator | 5 ++--- tests/std/tests/P2502R2_generator_promise/test.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/stl/inc/generator b/stl/inc/generator index 8b3a9d30260..524b9a22687 100644 --- a/stl/inc/generator +++ b/stl/inc/generator @@ -289,11 +289,10 @@ namespace _Gen_detail { template <_RANGES input_range _Rng, class _Alloc> requires convertible_to<_RANGES range_reference_t<_Rng>, _Yielded> _NODISCARD auto yield_value(_RANGES elements_of<_Rng, _Alloc> _Elem) { - using _Vty = _RANGES range_value_t<_Rng>; - using _Nested_awaitable = _Nested_awaitable_provider<_Yielded, _Vty, _Alloc>::_Awaitable; + using _Nested_awaitable = _Nested_awaitable_provider<_Yielded, void, _Alloc>::_Awaitable; auto _Lambda = [](allocator_arg_t, _Alloc, _RANGES iterator_t<_Rng> _It, - const _RANGES sentinel_t<_Rng> _Se) -> generator<_Yielded, _Vty, _Alloc> { + const _RANGES sentinel_t<_Rng> _Se) -> generator<_Yielded, void, _Alloc> { for (; _It != _Se; ++_It) { co_yield static_cast<_Yielded>(*_It); } diff --git a/tests/std/tests/P2502R2_generator_promise/test.cpp b/tests/std/tests/P2502R2_generator_promise/test.cpp index 7cd4a2323b2..ea1c71c10ef 100644 --- a/tests/std/tests/P2502R2_generator_promise/test.cpp +++ b/tests/std/tests/P2502R2_generator_promise/test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -226,6 +227,15 @@ struct Holder { struct Incomplete; #endif // ^^^ no workaround ^^^ +#if !(defined(__clang__) && defined(_M_IX86)) // TRANSITION, LLVM-56507 +// Also test LWG-4119: +// "generator::promise_type::yield_value(ranges::elements_of)'s nested generator may be ill-formed" +generator> test_lwg_4119() { // COMPILE-ONLY + vector> v; + co_yield ranges::elements_of(v); +} +#endif // ^^^ no workaround ^^^ + int main() { test_with_type(); test_with_type(); From 22b55733da4043cff493ee6e73f366a4b319bac2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:57:08 +0800 Subject: [PATCH 23/33] Implement LWG-4027 `possibly-const-range` should prefer returning `const R&` (#5221) Co-authored-by: Stephan T. Lavavej --- stl/inc/xutility | 2 +- tests/std/tests/P0896R4_views_join/test.cpp | 2 +- tests/std/tests/P0896R4_views_lazy_split/test.cpp | 8 ++++++++ tests/std/tests/P0896R4_views_transform/test.cpp | 7 +++++++ .../tests/P2278R4_ranges_const_range_machinery/test.cpp | 4 ++-- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index f1f33652ce7..3a0592c74c6 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2893,7 +2893,7 @@ namespace ranges { template _NODISCARD _MSVC_INTRINSIC constexpr auto& _Possibly_const_range(_Rng& _Range) noexcept { - if constexpr (constant_range && !constant_range<_Rng>) { + if constexpr (input_range) { return _STD as_const(_Range); } else { return _Range; diff --git a/tests/std/tests/P0896R4_views_join/test.cpp b/tests/std/tests/P0896R4_views_join/test.cpp index d909d97b9c7..2e14c108161 100644 --- a/tests/std/tests/P0896R4_views_join/test.cpp +++ b/tests/std/tests/P0896R4_views_join/test.cpp @@ -269,7 +269,7 @@ constexpr bool test_one(Outer&& rng, Expected&& expected) { static_assert(CanMemberCEnd == (forward_range && is_reference_v> && input_range>) ); - const same_as> auto cs = r.end(); + const auto cs = r.end(); if (!is_empty) { if constexpr (bidirectional_range && common_range) { assert(*prev(cs) == *prev(end(expected))); diff --git a/tests/std/tests/P0896R4_views_lazy_split/test.cpp b/tests/std/tests/P0896R4_views_lazy_split/test.cpp index e2aa5b8664e..6900be50a85 100644 --- a/tests/std/tests/P0896R4_views_lazy_split/test.cpp +++ b/tests/std/tests/P0896R4_views_lazy_split/test.cpp @@ -359,6 +359,14 @@ constexpr bool test_lwg_3904() { return j != r.end(); } +void test_lwg_4027() { // COMPILE-ONLY + auto r = views::single(0) | views::lazy_split(0); + using R1 = decltype((*ranges::cbegin(r)).front()); + using R2 = decltype((*cbegin(r)).front()); + static_assert(same_as); + static_assert(is_const_v>); +} + int main() { static_assert(instantiation_test()); instantiation_test(); diff --git a/tests/std/tests/P0896R4_views_transform/test.cpp b/tests/std/tests/P0896R4_views_transform/test.cpp index eb2c729102d..4c543fa6db2 100644 --- a/tests/std/tests/P0896R4_views_transform/test.cpp +++ b/tests/std/tests/P0896R4_views_transform/test.cpp @@ -879,6 +879,13 @@ void test_gh_3014() { // COMPILE-ONLY [[maybe_unused]] decltype(as_const(r).begin()) i = r.begin(); // Check 'iterator(iterator i)' } +void test_lwg_4027() { // COMPILE-ONLY + auto r = views::single(0) | views::transform([](int) { return 0; }); + using CIt1 = decltype(ranges::cbegin(r)); + using CIt2 = decltype(cbegin(r)); + static_assert(same_as); +} + int main() { { // Validate copyable views constexpr span s{some_ints}; diff --git a/tests/std/tests/P2278R4_ranges_const_range_machinery/test.cpp b/tests/std/tests/P2278R4_ranges_const_range_machinery/test.cpp index 30583ee42fb..fe49cd330f1 100644 --- a/tests/std/tests/P2278R4_ranges_const_range_machinery/test.cpp +++ b/tests/std/tests/P2278R4_ranges_const_range_machinery/test.cpp @@ -127,8 +127,8 @@ namespace test_prvalue_range { static_assert(CanRangeConstIterator); static_assert(CanRangeConstSentinel); static_assert(CanRangeConstReference); - static_assert(same_as, const_iterator>>); - static_assert(same_as, const_iterator>>); + static_assert(!same_as, const_iterator>>); + static_assert(!same_as, const_iterator>>); static_assert(same_as, int>); static_assert(ranges::constant_range); From 9ec1309a9dfa48abd07d7c7e429c510489df00c0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 17:59:00 +0800 Subject: [PATCH 24/33] ``: Fix dispatching for `views::counted` (#5223) --- stl/inc/ranges | 5 +-- tests/std/include/range_algorithm_support.hpp | 28 ++++++------ .../std/tests/P0896R4_views_counted/test.cpp | 44 ++++++++++++++++++- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index 38289d7320a..49b69fa59e9 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -4216,12 +4216,11 @@ namespace ranges { using _Decayed = decay_t<_It>; _STL_INTERNAL_STATIC_ASSERT(input_or_output_iterator<_Decayed>); if constexpr (contiguous_iterator<_Decayed>) { - return {_St::_Span, - noexcept(span(_STD to_address(_STD declval<_It>()), iter_difference_t<_Decayed>{}))}; + return {_St::_Span, true}; } else if constexpr (random_access_iterator<_Decayed>) { return {_St::_Subrange, noexcept(subrange(_STD declval<_It>(), _STD declval<_It>() + iter_difference_t<_Decayed>{}))}; - } else if constexpr (constructible_from<_Decayed, _It>) { + } else if constexpr (is_convertible_v<_It, _Decayed>) { return {_St::_Subrange_counted, noexcept(subrange( counted_iterator(_STD declval<_It>(), iter_difference_t<_Decayed>{}), default_sentinel))}; diff --git a/tests/std/include/range_algorithm_support.hpp b/tests/std/include/range_algorithm_support.hpp index 056b84b2982..96b44d2616a 100644 --- a/tests/std/include/range_algorithm_support.hpp +++ b/tests/std/include/range_algorithm_support.hpp @@ -964,7 +964,12 @@ namespace test { requires std::signed_integral && requires { typename std::iterator_traits::iterator_category; } struct redifference_iterator_category_base { using iterator_category = std::iterator_traits::iterator_category; - using iterator_concept = decltype([] { + }; + + template + class redifference_iterator : public redifference_iterator_category_base { + public: + using iterator_concept = decltype([] { if constexpr (std::contiguous_iterator) { return std::contiguous_iterator_tag{}; } else if constexpr (std::random_access_iterator) { @@ -977,13 +982,8 @@ namespace test { return std::input_iterator_tag{}; } }()); - }; - - template - class redifference_iterator : public redifference_iterator_category_base { - public: - using value_type = std::iter_value_t; - using difference_type = Diff; + using value_type = std::iter_value_t; + using difference_type = Diff; redifference_iterator() = default; constexpr explicit redifference_iterator(It it) : i_{std::move(it)} {} @@ -1052,22 +1052,22 @@ namespace test { return i.i_ == j.i_; } - [[nodiscard]] friend constexpr redifference_iterator operator+( - const redifference_iterator& it, std::same_as auto n) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator+(const redifference_iterator& it, I n) requires std::random_access_iterator { return redifference_iterator{it.i_ + static_cast>(n)}; } - [[nodiscard]] friend constexpr redifference_iterator operator+( - std::same_as auto n, const redifference_iterator& it) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator+(I n, const redifference_iterator& it) requires std::random_access_iterator { return redifference_iterator{it.i_ + static_cast>(n)}; } - [[nodiscard]] friend constexpr redifference_iterator operator-( - const redifference_iterator& it, std::same_as auto n) + template I> // TRANSITION, DevCom-10735214, should be abbreviated + [[nodiscard]] friend constexpr redifference_iterator operator-(const redifference_iterator& it, I n) requires std::random_access_iterator { return redifference_iterator{it.i_ - static_cast>(n)}; diff --git a/tests/std/tests/P0896R4_views_counted/test.cpp b/tests/std/tests/P0896R4_views_counted/test.cpp index a033fb72643..e20d1177c26 100644 --- a/tests/std/tests/P0896R4_views_counted/test.cpp +++ b/tests/std/tests/P0896R4_views_counted/test.cpp @@ -14,6 +14,12 @@ template concept Countable = requires { typename iter_difference_t>; } && requires(I&& i, iter_difference_t> n) { views::counted(forward(i), n); }; +template +concept CanConstructCountedSubrange = requires { typename iter_difference_t>; } + && requires(I&& i, iter_difference_t> n) { + ranges::subrange(counted_iterator(forward(i), n), default_sentinel); + }; + template struct convertible_difference { constexpr convertible_difference(const int _val_) noexcept : _val(_val_) {} @@ -31,8 +37,7 @@ struct instantiator { template static constexpr void call() { - using ranges::contiguous_range, ranges::equal, ranges::iterator_t, ranges::random_access_range, ranges::size, - ranges::subrange; + using ranges::equal, ranges::size, ranges::subrange; int input[] = {13, 42, 1729, -1, -1}; static_assert(Countable); @@ -41,6 +46,10 @@ struct instantiator { auto result = ranges::views::counted(Iter{input}, convertible_difference{3}); if constexpr (contiguous_iterator) { static_assert(same_as>, dynamic_extent>>); + + const test::redifference_iterator<_Signed128, Iter> rediff_it{Iter{input}}; + ranges::contiguous_range auto rediff_result = ranges::views::counted(rediff_it, _Signed128{4}); + assert(size(rediff_result) == 4); } else if constexpr (random_access_iterator) { static_assert(same_as>); } else { @@ -53,6 +62,37 @@ struct instantiator { } }; +// Also test GH-5183: ": views::counted::_Choose() misses difference casting for contiguous_iterator case" +struct ExplicitCopyCtorIter { + using difference_type = int; + + ExplicitCopyCtorIter() = default; + ExplicitCopyCtorIter(ExplicitCopyCtorIter&&) = default; + ExplicitCopyCtorIter& operator=(ExplicitCopyCtorIter&&) = default; + explicit ExplicitCopyCtorIter(const ExplicitCopyCtorIter&) = default; + int operator*(); + ExplicitCopyCtorIter& operator++(); + void operator++(int); +}; +static_assert(!Countable); +static_assert(!CanConstructCountedSubrange); + +struct ImplicitCopyOnlyIter { + using difference_type = int; + + ImplicitCopyOnlyIter() = default; + ImplicitCopyOnlyIter(ImplicitCopyOnlyIter&&) = default; + ImplicitCopyOnlyIter& operator=(ImplicitCopyOnlyIter&&) = default; + explicit ImplicitCopyOnlyIter(const ImplicitCopyOnlyIter&) = delete; + template + ImplicitCopyOnlyIter(const ImplicitCopyOnlyIter&); + int operator*(); + ImplicitCopyOnlyIter& operator++(); + void operator++(int); +}; +static_assert(Countable); +static_assert(CanConstructCountedSubrange); + int main() { static_assert(with_writable_iterators::call()); with_writable_iterators::call(); From 857831487af1ce833c17867862e981b144a5f27d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Jan 2025 18:01:18 +0800 Subject: [PATCH 25/33] Implement LWG-3886 Monad mo' problems (in `optional` and `expected`) (#5232) Co-authored-by: Stephan T. Lavavej --- stl/inc/expected | 42 +++--- stl/inc/optional | 25 ++-- tests/std/tests/P0220R1_optional/test.cpp | 154 +++++++++++++++++++-- tests/std/tests/P0323R12_expected/test.cpp | 131 ++++++++++++++++++ 4 files changed, 315 insertions(+), 37 deletions(-) diff --git a/stl/inc/expected b/stl/inc/expected index 79e934a52cd..f27e3fc7007 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -304,7 +304,7 @@ public: } } - template + template > requires (!is_same_v, in_place_t> && !is_same_v, expected> && !_Is_specialization_v, unexpected> && (!is_same_v, bool> @@ -469,7 +469,7 @@ public: && _Trivially_move_constructible_assignable_destructible<_Err> = default; - template + template > requires (!is_same_v, expected> && !_Is_specialization_v, unexpected> && is_constructible_v<_Ty, _Uty> && is_assignable_v<_Ty&, _Uty> && (is_nothrow_constructible_v<_Ty, _Uty> || is_nothrow_move_constructible_v<_Ty> @@ -730,32 +730,38 @@ public: return _STD move(_Unexpected); } - template - _NODISCARD constexpr _Ty value_or(_Uty&& _Other) const& noexcept( - is_nothrow_copy_constructible_v<_Ty> && is_nothrow_convertible_v<_Uty, _Ty>) /* strengthened */ { - static_assert( - is_copy_constructible_v<_Ty>, "is_copy_constructible_v must be true. (N4950 [expected.object.obs]/18)"); - static_assert( - is_convertible_v<_Uty, _Ty>, "is_convertible_v must be true. (N4950 [expected.object.obs]/18)"); + template > + _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) const& noexcept( + is_nothrow_convertible_v> + && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ { + static_assert(is_convertible_v>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/18 as modified by LWG-3424)"); + static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/18 as modified by LWG-3424)"); if (_Has_value) { return _Value; } else { - return static_cast<_Ty>(_STD forward<_Uty>(_Other)); + return static_cast>(_STD forward<_Uty>(_Other)); } } - template - _NODISCARD constexpr _Ty value_or(_Uty&& _Other) && noexcept( - is_nothrow_move_constructible_v<_Ty> && is_nothrow_convertible_v<_Uty, _Ty>) /* strengthened */ { - static_assert( - is_move_constructible_v<_Ty>, "is_move_constructible_v must be true. (N4950 [expected.object.obs]/20)"); - static_assert( - is_convertible_v<_Uty, _Ty>, "is_convertible_v must be true. (N4950 [expected.object.obs]/20)"); + template > + _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) && noexcept( + is_nothrow_convertible_v<_Ty, remove_cv_t<_Ty>> + && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ { + static_assert(is_convertible_v<_Ty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/20 as modified by LWG-3424)"); + static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>, + "is_convertible_v> must be true. " + "(N5001 [expected.object.obs]/20 as modified by LWG-3424)"); if (_Has_value) { return _STD move(_Value); } else { - return static_cast<_Ty>(_STD forward<_Uty>(_Other)); + return static_cast>(_STD forward<_Uty>(_Other)); } } diff --git a/stl/inc/optional b/stl/inc/optional index 2aae7cd4dd3..28e41c46abf 100644 --- a/stl/inc/optional +++ b/stl/inc/optional @@ -252,7 +252,7 @@ public: negation, bool>, _Is_specialization<_Remove_cvref_t<_Ty2>, optional>>>, is_constructible<_Ty, _Ty2>>>; - template ::value, int> = 0> + template , enable_if_t<_AllowDirectConversion<_Ty2>::value, int> = 0> constexpr explicit(!is_convertible_v<_Ty2, _Ty>) optional(_Ty2&& _Right) noexcept(is_nothrow_constructible_v<_Ty, _Ty2>) // strengthened : _Mybase(in_place, _STD forward<_Ty2>(_Right)) {} @@ -288,10 +288,11 @@ public: return *this; } - template >>, - negation, is_same<_Ty, decay_t<_Ty2>>>>, - is_constructible<_Ty, _Ty2>, is_assignable<_Ty&, _Ty2>>, - int> = 0> + template , + enable_if_t>>, + negation, is_same<_Ty, decay_t<_Ty2>>>>, is_constructible<_Ty, _Ty2>, + is_assignable<_Ty&, _Ty2>>, + int> = 0> _CONSTEXPR20 optional& operator=(_Ty2&& _Right) noexcept(is_nothrow_assignable_v<_Ty&, _Ty2> && is_nothrow_constructible_v<_Ty, _Ty2>) /* strengthened */ { this->_Assign(_STD forward<_Ty2>(_Right)); @@ -425,13 +426,14 @@ public: return _STD move(this->_Value); } - template + template > _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Ty2&& _Right) const& { static_assert(is_convertible_v>, "The const overload of optional::value_or requires const T& to be convertible to remove_cv_t " "(N4950 [optional.observe]/15 as modified by LWG-3424)."); - static_assert(is_convertible_v<_Ty2, _Ty>, - "optional::value_or(U) requires U to be convertible to T (N4950 [optional.observe]/15)."); + static_assert(is_convertible_v<_Ty2, remove_cv_t<_Ty>>, + "optional::value_or(U) requires U to be convertible to remove_cv_t " + "(N4950 [optional.observe]/15 as modified by LWG-3424)."); if (this->_Has_value) { return static_cast(this->_Value); @@ -439,13 +441,14 @@ public: return static_cast>(_STD forward<_Ty2>(_Right)); } - template + template > _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Ty2&& _Right) && { static_assert(is_convertible_v<_Ty, remove_cv_t<_Ty>>, "The rvalue overload of optional::value_or requires T to be convertible to remove_cv_t " "(N4950 [optional.observe]/17 as modified by LWG-3424)."); - static_assert(is_convertible_v<_Ty2, _Ty>, - "optional::value_or(U) requires U to be convertible to T (N4950 [optional.observe]/17)."); + static_assert(is_convertible_v<_Ty2, remove_cv_t<_Ty>>, + "optional::value_or(U) requires U to be convertible to remove_cv_t " + "(N4950 [optional.observe]/17 as modified by LWG-3424)."); if (this->_Has_value) { return static_cast<_Ty&&>(this->_Value); diff --git a/tests/std/tests/P0220R1_optional/test.cpp b/tests/std/tests/P0220R1_optional/test.cpp index 34ed93ae66e..af8fe440199 100644 --- a/tests/std/tests/P0220R1_optional/test.cpp +++ b/tests/std/tests/P0220R1_optional/test.cpp @@ -8372,6 +8372,11 @@ int run_test() #include #include +#if _HAS_CXX20 +#define CONSTEXPR20 constexpr +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define CONSTEXPR20 inline +#endif // ^^^ !_HAS_CXX20 ^^^ namespace msvc { namespace size { @@ -8422,12 +8427,6 @@ namespace msvc { namespace lwg3836 { static_assert(std::is_convertible_v, std::optional>); static_assert(std::is_convertible_v&, std::optional>); - -#if _HAS_CXX20 -#define CONSTEXPR20 constexpr -#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv -#define CONSTEXPR20 inline -#endif // ^^^ !_HAS_CXX20 ^^^ CONSTEXPR20 bool run_test() { std::optional oi = 0; std::optional ob = oi; @@ -8436,13 +8435,151 @@ namespace msvc { return true; } -#undef CONSTEXPR20 - #if _HAS_CXX20 static_assert(run_test()); #endif // _HAS_CXX20 } // namespace lwg3836 + namespace lwg3886 { + enum class Qualification { + None, + Const, + Volatile, + ConstVolatile, + }; + + template + constexpr Qualification CvQualOf = + std::is_const_v> + ? (std::is_volatile_v> ? Qualification::ConstVolatile : Qualification::Const) + : (std::is_volatile_v> ? Qualification::Volatile : Qualification::None); + + struct QualDistinction { + QualDistinction() = default; + + constexpr QualDistinction(QualDistinction&&) noexcept : qual_{Qualification::None} {} + constexpr QualDistinction(const QualDistinction&) noexcept : qual_{Qualification::Const} {} + template >, QualDistinction>, int> = + 0> + constexpr QualDistinction(T&&) noexcept : qual_{CvQualOf} {} + + constexpr QualDistinction& operator=(QualDistinction&&) noexcept { + qual_ = Qualification::None; + return *this; + } + constexpr QualDistinction& operator=(const QualDistinction&) noexcept { + qual_ = Qualification::Const; + return *this; + } + template >, QualDistinction>, int> = + 0> + constexpr QualDistinction& operator=(T&&) noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + constexpr const QualDistinction& operator=(T&&) const noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + volatile QualDistinction& operator=(T&&) volatile noexcept { + qual_ = CvQualOf; + return *this; + } + template >, QualDistinction>, int> = + 0> + const volatile QualDistinction& operator=(T&&) const volatile noexcept { + qual_ = CvQualOf; + return *this; + } + + mutable Qualification qual_ = Qualification::None; + }; + + constexpr bool test_value_or() { + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + return true; + } + + CONSTEXPR20 bool test_assignment() { + assert((std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + assert((std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + return true; + } + + bool test_volatile() { + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + assert(std::optional{}.value_or({}).qual_ == Qualification::None); + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + { + std::optional opt; + assert(opt.value_or({}).qual_ == Qualification::None); + } + + assert( + (std::optional{} = {QualDistinction{}}).value().qual_ == Qualification::None); + assert((std::optional{} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + { + std::optional opt{std::in_place}; + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + opt.reset(); + assert((opt = {QualDistinction{}}).value().qual_ == Qualification::None); + } + + return true; + } + + static_assert(test_value_or()); +#if _HAS_CXX20 + static_assert(test_assignment()); +#endif // _HAS_CXX20 + + void run_test() { + test_value_or(); + test_assignment(); + test_volatile(); + } + } // namespace lwg3886 + namespace vso406124 { // Defend against regression of VSO-406124 void run_test() { @@ -8719,6 +8856,7 @@ int main() { optional_includes_initializer_list::run_test(); msvc::lwg3836::run_test(); + msvc::lwg3886::run_test(); msvc::vso406124::run_test(); msvc::vso508126::run_test(); diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index ba0e7f4d685..81335d3a8b3 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -2316,6 +2316,133 @@ void test_lwg_3843() { } } +// Test LWG-3886: "Monad mo' problems (in optional and expected)" + +enum class Qualification { + None, + Const, + Volatile, + ConstVolatile, +}; + +template +constexpr Qualification CvQualOf = + is_const_v> + ? (is_volatile_v> ? Qualification::ConstVolatile : Qualification::Const) + : (is_volatile_v> ? Qualification::Volatile : Qualification::None); + +struct QualDistinction { + QualDistinction() = default; + + constexpr QualDistinction(QualDistinction&&) noexcept : qual_{Qualification::None} {} + constexpr QualDistinction(const QualDistinction&) noexcept : qual_{Qualification::Const} {} + template + requires is_same_v, QualDistinction> + constexpr QualDistinction(T&&) noexcept : qual_{CvQualOf} {} + + constexpr QualDistinction& operator=(QualDistinction&&) noexcept { + qual_ = Qualification::None; + return *this; + } + constexpr QualDistinction& operator=(const QualDistinction&) noexcept { + qual_ = Qualification::Const; + return *this; + } + template + requires is_same_v, QualDistinction> + constexpr QualDistinction& operator=(T&&) noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + constexpr const QualDistinction& operator=(T&&) const noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + volatile QualDistinction& operator=(T&&) volatile noexcept { + qual_ = CvQualOf; + return *this; + } + template + requires is_same_v, QualDistinction> + const volatile QualDistinction& operator=(T&&) const volatile noexcept { + qual_ = CvQualOf; + return *this; + } + + mutable Qualification qual_ = Qualification::None; +}; + +constexpr bool test_lwg_3886() { + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } + + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert( + (expected{unexpect} = {QualDistinction{}}).value().qual_ == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ + + return true; +} + +void test_lwg_3886_volatile() { + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ + + assert((expected{unexpect}.value_or({}).qual_ == Qualification::None)); + { + expected ex{unexpect}; + assert(ex.value_or({}).qual_ == Qualification::None); + } +#if 0 // TRANSITION, LWG-3891 + assert((expected{unexpect} = {QualDistinction{}}).value().qual_ + == Qualification::None); + { + expected ex{in_place}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + ex = unexpected{'*'}; + assert((ex = {QualDistinction{}}).value().qual_ == Qualification::None); + } +#endif // ^^^ no workaround ^^^ +} + // Test GH-4011: these predicates triggered constraint recursion. static_assert(copyable>); static_assert(copyable>); @@ -2389,6 +2516,8 @@ static_assert(!is_assignable_v&, ambiguating_expected_assign static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); static_assert(!is_assignable_v&, ambiguating_expected_assignment_source>); +static_assert(test_lwg_3886()); + int main() { test_unexpected::test_all(); static_assert(test_unexpected::test_all()); @@ -2405,5 +2534,7 @@ int main() { test_reinit_regression(); test_lwg_3843(); + test_lwg_3886(); + test_lwg_3886_volatile(); test_inherited_constructors(); } From 8124540f8bce3faad76a6dddd050f9a69af4b87d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 15 Jan 2025 04:43:20 -0800 Subject: [PATCH 26/33] Update llvm-project (#5235) --- llvm-project | 2 +- tests/libcxx/expected_results.txt | 144 ++++++++++++++++++++++++++---- 2 files changed, 129 insertions(+), 17 deletions(-) diff --git a/llvm-project b/llvm-project index 69ead949d08..63d3bd6d0ca 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 69ead949d08ff0bb8cbbf4f7143aaa6687830f6b +Subproject commit 63d3bd6d0caf8185aba49540fe2f67512fdf3a98 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 824dd2f7314..1f09a82fe49 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -41,12 +41,6 @@ std/input.output/iostream.format/output.streams/ostream.formatted/ostream.format std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL -# LLVM-119174: [libcxx][test] Silence nodiscard warnings for std::expected -std/utilities/expected/expected.expected/monadic/and_then.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/or_else.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/transform.pass.cpp FAIL -std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp FAIL - # LLVM-122638: [libc++][test] re.regex.construct/bad_backref.pass.cpp assumes non-standard extension to extended regular expressions std/re/re.regex/re.regex.construct/bad_backref.pass.cpp FAIL @@ -231,6 +225,93 @@ std/input.output/syncstream/osyncstream/thread/several_threads.pass.cpp:1 SKIPPE std/depr/depr.c.headers/uchar_h.compile.pass.cpp FAIL std/strings/c.strings/cuchar.compile.pass.cpp FAIL +# P0429R9 +std/containers/container.adaptors/flat.map.syn/sorted_unique.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_rv_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.capacity/empty.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.capacity/max_size.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.capacity/size.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/alloc.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/assign_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/compare.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/containers.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy_alloc.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.addressof.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/copy.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/default_noexcept.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/default.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/dtor_noexcept.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_alloc.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign_clears.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign_noexcept.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_assign.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_exceptions.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/move.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/pmr.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_container.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/sorted_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.erasure/erase_if_exceptions.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.erasure/erase_if.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator_comparison.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator_concept_conformance.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/iterator.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/range_concept_conformance.compile.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/clear.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/extract.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_cv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_cv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_iter_rv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_rv.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_sorted_initializer_list.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_sorted_iter_iter.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/replace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.observers/comp.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.observers/keys_values.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/contains.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/count.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/equal_range.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/find.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp FAIL +std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound.pass.cpp FAIL +std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp FAIL +std/containers/container.adaptors/flat.map/op_compare.pass.cpp FAIL +std/containers/container.adaptors/flat.map/types.compile.pass.cpp FAIL + # P0533R9 constexpr For And std/language.support/support.limits/support.limits.general/cmath.version.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/cstdlib.version.compile.pass.cpp FAIL @@ -359,12 +440,6 @@ std/utilities/meta/meta.unary/meta.unary.prop/has_unique_object_representations. # *** CLANG ISSUES, NOT YET ANALYZED *** -# Clang doesn't enable sized deallocation by default. Should we add -fsized-deallocation or do something else? -std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.pass.cpp:2 SKIPPED -std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp:2 SKIPPED - # Not analyzed. Clang apparently defines platform macros differently from C1XX. std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp:2 FAIL @@ -372,6 +447,10 @@ std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp:2 FAIL std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp:2 FAIL +# Not analyzed. __cpp_sized_deallocation isn't being defined by Clang. +std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp:2 FAIL +std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp:2 FAIL + # *** STL BUGS *** # GH-784 : aligned_storage has incorrect alignment defaults @@ -564,16 +643,35 @@ std/utilities/memory/pointer.conversion/to_address_without_pointer_traits.pass.c # We disagree about whether various chrono types should be optimized, and the test is clearly wrong about vector::reference. std/utilities/format/format.formatter/format.formatter.locking/enable_nonlocking_formatter_optimization.compile.pass.cpp FAIL -# `increasing_allocator` calls `std::allocator::deallocate` with the wrong size -std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp FAIL -std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp FAIL - # We disagree on the syntax flags set by the default basic_regex constructor: we set 0, libc++ sets ECMAScript. # Relates to LWG-3604. std/re/re.regex/re.regex.construct/default.pass.cpp FAIL std/re/re.regex/re.regex.nonmemb/re.regex.nmswap/swap.pass.cpp FAIL std/re/re.regex/re.regex.swap/swap.pass.cpp FAIL +# Test emits a Clang -Wself-move warning, so it should avoid the self-move or suppress the warning. +std/containers/sequences/vector/addressof.compile.pass.cpp:2 FAIL + +# throwing_allocator appears to be totally non-Standard. +std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp FAIL + +# The test is checking _LIBCPP_HAS_THREADS, which we don't have. +std/language.support/support.limits/support.limits.general/shared_mutex.version.compile.pass.cpp FAIL + +# x64 truncation warnings caused by allocators. +std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp:1 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp:1 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp:0 SKIPPED +std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp:1 SKIPPED + +# Instantiating istreambuf_iterator requires _Traits to be complete. +# However, when only is included, char_traits is merely forward-declared in our implementation. +# The definition of char_traits isn't required to be provided by , so this test appears to be bogus. +# error: incomplete type 'std::char_traits' named in nested name specifier +std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp FAIL + # *** LIKELY STL BUGS *** # Not analyzed, likely STL bugs. Various assertions. @@ -886,6 +984,7 @@ std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp FAIL std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp FAIL std/containers/sequences/vector.bool/append_range.pass.cpp FAIL std/containers/sequences/vector.bool/assign_range.pass.cpp FAIL +std/containers/sequences/vector.bool/flip.pass.cpp FAIL std/containers/sequences/vector.bool/insert_range.pass.cpp FAIL std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp FAIL std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp FAIL @@ -1083,6 +1182,7 @@ std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/recursion_pen std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.absolute/absolute.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp SKIPPED +std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.copy/copy.pass.cpp SKIPPED @@ -1195,6 +1295,14 @@ std/numerics/c.math/hermite.pass.cpp FAIL # Not analyzed. Test coverage for LLVM-104496 uses span. std/containers/views/views.span/span.cons/copy.pass.cpp FAIL +# Not analyzed. These tests disable or limit allocations, which interferes with our proxy objects. +std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp FAIL +std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp FAIL + +# Not analyzed. Our stdalign.h doesn't define __alignas_is_defined in C++ mode. +std/depr/depr.c.headers/stdalign_h.compile.pass.cpp:0 FAIL +std/depr/depr.c.headers/stdalign_h.compile.pass.cpp:1 FAIL + # *** XFAILS WHICH PASS *** # These tests contain `// XFAIL: msvc` comments, which accurately describe runtime failures for x86 and x64. @@ -1280,3 +1388,7 @@ std/iterators/iterator.container/ssize.LWG3207.compile.pass.cpp:9 SKIPPED # This test is marked as `REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector`. # Listing these on separate lines would allow magic_comments.txt to recognize it. std/containers/sequences/vector/vector.modifiers/assert.push_back.invalidation.pass.cpp:9 SKIPPED + +# This test is marked as `REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-std-array`. +# Listing these on separate lines would allow magic_comments.txt to recognize it. +std/containers/sequences/array/assert.iterators.pass.cpp:9 SKIPPED From 01900428a32b0c19740ed3fe853a1f3b544d47d4 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 24 Jan 2025 08:37:00 -0800 Subject: [PATCH 27/33] Toolset update: VS 2022 17.13 Preview 3, Clang 19.1.1 (#5247) --- .clang-format | 46 ++++- README.md | 4 +- azure-devops/config.yml | 2 +- azure-devops/provision-image.ps1 | 2 +- stl/inc/__msvc_heap_algorithms.hpp | 4 +- stl/inc/__msvc_int128.hpp | 3 +- stl/inc/atomic | 3 +- stl/inc/compare | 6 +- stl/inc/deque | 2 +- stl/inc/execution | 2 + stl/inc/functional | 7 +- stl/inc/hash_map | 5 - stl/inc/hash_set | 5 - stl/inc/map | 20 +-- stl/inc/mdspan | 10 +- stl/inc/queue | 24 +-- stl/inc/ranges | 16 +- stl/inc/regex | 6 +- stl/inc/set | 4 +- stl/inc/type_traits | 12 +- stl/inc/unordered_map | 70 ++++---- stl/inc/unordered_set | 61 ++++--- stl/inc/utility | 2 +- stl/inc/variant | 9 +- stl/inc/xhash | 5 - stl/inc/xlocale | 2 + stl/inc/xlocnum | 8 +- stl/inc/xloctime | 4 +- stl/inc/xmemory | 8 +- stl/inc/xstring | 12 +- stl/inc/xutility | 15 +- stl/inc/yvals_core.h | 4 +- stl/src/excptptr.cpp | 4 +- stl/src/locale.cpp | 4 +- stl/src/multprec.cpp | 4 +- stl/src/xstoul.cpp | 2 +- stl/src/xstoull.cpp | 2 +- stl/src/xwcsxfrm.cpp | 4 +- tests/libcxx/expected_results.txt | 161 ++++++++---------- .../instantiate_algorithms_op_deref.hpp | 4 +- tests/std/tests/Dev08_563686_ostream/test.cpp | 4 +- .../test.cpp | 4 +- .../test.cpp | 2 +- .../Dev09_173612_tr1_regex_leak/test.cpp | 4 +- .../Dev10_491486_floating_point_hash/test.cpp | 4 +- .../Dev10_561430_list_and_tree_leaks/test.cpp | 8 +- .../test.cpp | 2 +- .../Dev11_0617384_empty_std_function/test.cpp | 2 +- .../std/tests/Dev11_0836436_get_time/test.cpp | 4 +- .../GH_001858_iostream_exception/test.cpp | 6 +- .../test.compile.pass.cpp | 8 +- .../P0009R18_mdspan_layout_left/test.cpp | 2 +- .../P0009R18_mdspan_layout_right/test.cpp | 2 +- .../P0009R18_mdspan_layout_stride/test.cpp | 14 +- .../std/tests/P0009R18_mdspan_mdspan/test.cpp | 30 ++-- .../test.cpp | 4 +- .../P0083R3_splicing_maps_and_sets/test.cpp | 10 +- tests/std/tests/P0218R1_filesystem/test.cpp | 4 +- tests/std/tests/P0220R1_string_view/test.cpp | 14 +- .../tests/P0288R9_move_only_function/test.cpp | 17 +- .../P0414R2_shared_ptr_for_arrays/test.cpp | 22 +-- .../tests/P0433R2_deduction_guides/test.cpp | 3 +- .../test.cpp | 1 - .../P0674R1_make_shared_for_arrays/test.cpp | 4 +- .../tests/P0896R4_common_iterator/test.cpp | 2 +- .../test.compile.pass.cpp | 2 +- .../test.cpp | 2 +- tests/std/tests/P0896R4_views_iota/test.cpp | 2 +- .../tests/P0898R3_concepts/invocable_cc.hpp | 4 +- .../custom_format.py | 2 +- .../test.compile.pass.cpp | 2 +- .../std/tests/P2278R4_views_as_const/test.cpp | 16 +- tests/std/tests/P2474R2_views_repeat/test.cpp | 4 - tests/std/tests/P2502R2_generator/test.cpp | 11 +- .../tests/P2502R2_generator_death/test.cpp | 5 + .../tests/P2502R2_generator_iterator/test.cpp | 9 +- .../VSO_0000000_any_calling_conventions/a.cpp | 4 +- .../VSO_0000000_any_calling_conventions/b.cpp | 4 +- .../test.cpp | 2 +- .../VSO_0000000_string_view_idl/test.cpp | 8 +- .../test.cpp | 4 +- .../test.cpp | 4 +- .../test.cpp | 4 +- .../test.compile.pass.cpp | 2 - tests/tr1/include/tfuns.h | 10 +- tests/tr1/include/typetr.h | 8 +- tests/tr1/tests/memory3/test.cpp | 4 +- tests/tr1/tests/scoped_allocator/test.cpp | 2 +- tools/format/CMakeLists.txt | 2 +- 89 files changed, 456 insertions(+), 406 deletions(-) diff --git a/.clang-format b/.clang-format index 0ffd390f783..035d0c1f84b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,13 +1,12 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# https://releases.llvm.org/18.1.8/tools/clang/docs/ClangFormatStyleOptions.html +# https://releases.llvm.org/19.1.0/tools/clang/docs/ClangFormatStyleOptions.html # To update this .clang-format file for a new clang-format version: # 1. Update the documentation link above. -# 2. Copy the output of `clang-format -dump-config` into a temporary file. +# 2. Copy the output of `clang-format -dump-config --style=LLVM` into a temporary file. # a. Comment out all of its lines. -# b. Uncomment `BasedOnStyle: LLVM`. # 3. Compare that temporary file to this .clang-format file. # 4. Adjust this .clang-format file to record new and updated options. # a. Read the new documentation to understand such changes. @@ -56,7 +55,29 @@ AlignConsecutiveMacros: Consecutive # Enabled: false # AcrossEmptyLines: false # AcrossComments: false +# AlignCaseArrows: false # AlignCaseColons: false +# AlignConsecutiveTableGenBreakingDAGArgColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false +# AlignConsecutiveTableGenCondOperatorColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false +# AlignConsecutiveTableGenDefinitionColons: +# Enabled: false +# AcrossEmptyLines: false +# AcrossComments: false +# AlignCompound: false +# AlignFunctionPointers: false +# PadOperators: false # AlignEscapedNewlines: Right AlignEscapedNewlines: Left # AlignOperands: Align @@ -71,6 +92,7 @@ AlignTrailingComments: # AllowBreakBeforeNoexceptSpecifier: Never AllowBreakBeforeNoexceptSpecifier: OnlyWithParen # AllowShortBlocksOnASingleLine: Never +# AllowShortCaseExpressionOnASingleLine: true # AllowShortCaseLabelsOnASingleLine: false # AllowShortCompoundRequirementOnASingleLine: true # AllowShortEnumsOnASingleLine: true @@ -80,10 +102,7 @@ AllowShortFunctionsOnASingleLine: Empty # AllowShortLambdasOnASingleLine: All # AllowShortLoopsOnASingleLine: false # AlwaysBreakAfterDefinitionReturnType: None -# AlwaysBreakAfterReturnType: None # AlwaysBreakBeforeMultilineStrings: false -# AlwaysBreakTemplateDeclarations: MultiLine -AlwaysBreakTemplateDeclarations: Yes # AttributeMacros: # - __capability # BinPackArguments: true @@ -112,6 +131,7 @@ AlwaysBreakTemplateDeclarations: Yes # BreakAfterAttributes: Leave BreakAfterAttributes: Never # BreakAfterJavaFieldAnnotations: false +# BreakAfterReturnType: None # BreakArrays: true # BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: NonAssignment @@ -120,8 +140,11 @@ BreakBeforeBinaryOperators: NonAssignment # BreakBeforeInlineASMColon: OnlyMultiline # BreakBeforeTernaryOperators: true # BreakConstructorInitializers: BeforeColon +# BreakFunctionDefinitionParameters: false # BreakInheritanceList: BeforeColon # BreakStringLiterals: true +# BreakTemplateDeclarations: MultiLine +BreakTemplateDeclarations: Yes # ColumnLimit: 80 ColumnLimit: 120 # CommentPragmas: '^ IWYU pragma:' @@ -202,14 +225,19 @@ InsertNewlineAtEOF: true # HexMinDigits: 0 # JavaScriptQuotes: Leave # JavaScriptWrapImports: true -# KeepEmptyLinesAtTheStartOfBlocks: true -# KeepEmptyLinesAtEOF: false +# KeepEmptyLines: +# AtEndOfFile: false +# AtStartOfBlock: true +# AtStartOfFile: true +KeepEmptyLines: + AtStartOfFile: false # LambdaBodyIndentation: Signature # LineEnding: DeriveLF LineEnding: CRLF # NOTE: MacroBlockBegin/MacroBlockEnd don't work with _CATCH_ALL. # MacroBlockBegin: '' # MacroBlockEnd: '' +# MainIncludeChar: Quote # MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 2 # NamespaceIndentation: None @@ -286,6 +314,7 @@ SpaceBeforeParensOptions: # Maximum: -1 # SpacesInParens: Never # SpacesInParensOptions: +# ExceptDoubleParentheses: false # InCStyleCasts: false # InConditionalStatements: false # InEmptyParentheses: false @@ -310,6 +339,7 @@ StatementMacros: - _FMT_P2286_END - _EXTERN_C_UNLESS_PURE - _END_EXTERN_C_UNLESS_PURE +# TableGenBreakInsideDAGArg: DontBreak # TabWidth: 8 # UseTab: Never # VerilogBreakBetweenInstancePorts: true diff --git a/README.md b/README.md index 23176d4326b..dc4ecd4b23a 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem # How To Build With The Visual Studio IDE -1. Install Visual Studio 2022 17.13 Preview 2 or later. +1. Install Visual Studio 2022 17.13 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * Select "MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)" in the VS Installer if you would like to build the ARM64/ARM64EC target. @@ -160,7 +160,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem # How To Build With A Native Tools Command Prompt -1. Install Visual Studio 2022 17.13 Preview 2 or later. +1. Install Visual Studio 2022 17.13 Preview 3 or later. * Select "Windows 11 SDK (10.0.22621.0)" in the VS Installer. * Select "MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)" in the VS Installer if you would like to build the ARM64/ARM64EC target. diff --git a/azure-devops/config.yml b/azure-devops/config.yml index ca89e088cf8..111b6eab4f3 100644 --- a/azure-devops/config.yml +++ b/azure-devops/config.yml @@ -5,7 +5,7 @@ variables: - name: poolName - value: 'StlBuild-2024-12-12T1002-Pool' + value: 'StlBuild-2025-01-22T1525-Pool' readonly: true - name: poolDemands value: 'EnableSpotVM -equals false' diff --git a/azure-devops/provision-image.ps1 b/azure-devops/provision-image.ps1 index 048bbd65d75..630b6676dd4 100644 --- a/azure-devops/provision-image.ps1 +++ b/azure-devops/provision-image.ps1 @@ -47,7 +47,7 @@ $PythonUrl = 'https://www.python.org/ftp/python/3.13.1/python-3.13.1-amd64.exe' $PythonArgs = @('/quiet', 'InstallAllUsers=1', 'PrependPath=1', 'CompileAll=1', 'Include_doc=0') $CudaUrl = 'https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_551.61_windows.exe' -$CudaArgs = @('-s') +$CudaArgs = @('-s', '-n', 'nvcc_12.4') <# .SYNOPSIS diff --git a/stl/inc/__msvc_heap_algorithms.hpp b/stl/inc/__msvc_heap_algorithms.hpp index 3a06b593456..f368fc70954 100644 --- a/stl/inc/__msvc_heap_algorithms.hpp +++ b/stl/inc/__msvc_heap_algorithms.hpp @@ -23,8 +23,8 @@ _CONSTEXPR20 void _Push_heap_by_index( _RanIt _First, _Iter_diff_t<_RanIt> _Hole, _Iter_diff_t<_RanIt> _Top, _Ty&& _Val, _Pr _Pred) { // percolate _Hole to _Top or where _Val belongs using _Diff = _Iter_diff_t<_RanIt>; - for (_Diff _Idx = (_Hole - 1) >> 1; // shift for codegen - _Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val); _Idx = (_Hole - 1) >> 1) { // shift for codegen + for (_Diff _Idx = (_Hole - 1) >> 1; // shift for codegen + _Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val); _Idx = (_Hole - 1) >> 1) { // shift for codegen // move _Hole up to parent *(_First + _Hole) = _STD move(*(_First + _Idx)); _Hole = _Idx; diff --git a/stl/inc/__msvc_int128.hpp b/stl/inc/__msvc_int128.hpp index 9a3f2e3c69b..7933e595820 100644 --- a/stl/inc/__msvc_int128.hpp +++ b/stl/inc/__msvc_int128.hpp @@ -23,7 +23,8 @@ #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv #define _TEMPLATE_CLASS_INTEGRAL(type) template , int> = 0> #define _ZERO_OR_NO_INIT \ - {} // Trivial default initialization is not allowed in constexpr functions before C++20. + { \ + } // Trivial default initialization is not allowed in constexpr functions before C++20. #endif // ^^^ !_HAS_CXX20 ^^^ #pragma pack(push, _CRT_PACKING) diff --git a/stl/inc/atomic b/stl/inc/atomic index e42a4033c90..e69bb281481 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -2817,7 +2817,8 @@ _EXPORT_STD using atomic_unsigned_lock_free = atomic_uintptr_t; #endif // _HAS_CXX20 #define ATOMIC_FLAG_INIT \ - {} + { \ + } _EXPORT_STD struct atomic_flag { // flag with test-and-set semantics #if _HAS_CXX20 diff --git a/stl/inc/compare b/stl/inc/compare index adc7730731a..37f9f7f40a2 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -282,9 +282,9 @@ inline constexpr unsigned char _Classify_category = _Comparison _EXPORT_STD template using common_comparison_category_t = - conditional_t<(_Classify_category<_Types...> & _Comparison_category_none) != 0, void, - conditional_t<(_Classify_category<_Types...> & _Comparison_category_partial) != 0, partial_ordering, - conditional_t<(_Classify_category<_Types...> & _Comparison_category_weak) != 0, weak_ordering, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_none) != 0), void, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_partial) != 0), partial_ordering, + conditional_t<((_Classify_category<_Types...> & _Comparison_category_weak) != 0), weak_ordering, strong_ordering>>>; _EXPORT_STD template diff --git a/stl/inc/deque b/stl/inc/deque index eed80fc0993..9bba528c614 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1012,7 +1012,7 @@ public: // deallocate unused blocks, traversing over the circular buffer until the first used block index for (auto _Block_idx = _First_unused_block_idx; _Block_idx != _First_used_block_idx; - _Block_idx = static_cast((_Block_idx + 1) & _Mask)) { + _Block_idx = static_cast((_Block_idx + 1) & _Mask)) { auto& _Block_ptr = _Map()[static_cast<_Map_difference_type>(_Block_idx)]; if (_Block_ptr != nullptr) { _Getal().deallocate(_Block_ptr, _Block_size); diff --git a/stl/inc/execution b/stl/inc/execution index 99801e6d75c..5f5134f768f 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -677,7 +677,9 @@ public: private: atomic _Bottom{0}; // modified by only owning thread atomic _Top{0}; // modified by all threads + // clang-format off: clang-format 19 doesn't understand _Guarded_by_ and will damage the following code _Guarded_by_(_Segment_lock) _Circular_buffer<_Ty>* _Segment { _Circular_buffer<_Ty>::_New_circular_buffer() }; + // clang-format on mutex _Segment_lock{}; }; diff --git a/stl/inc/functional b/stl/inc/functional index aa5519259c9..7ed26be7e7c 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -580,7 +580,7 @@ public: }; _EXPORT_STD template -_NODISCARD _CONSTEXPR20 _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::*_Pm) noexcept { +_NODISCARD _CONSTEXPR20 _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::* _Pm) noexcept { return _Mem_fn<_Rx _Ty::*>(_Pm); } @@ -2341,9 +2341,8 @@ _NODISCARD constexpr auto bind_front(_Fx&& _Func, _Types&&... _Args) { template constexpr auto _Call_back_binder(index_sequence<_Ix...>, _Cv_FD&& _Obj, _Cv_tuple_TiD&& _Tpl, _Unbound&&... _Unbargs) noexcept(noexcept(_STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., - _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...))) - -> decltype(_STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., - _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...)) { + _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...))) -> decltype(_STD invoke(_STD forward<_Cv_FD>(_Obj), + _STD forward<_Unbound>(_Unbargs)..., _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...)) { return _STD invoke(_STD forward<_Cv_FD>(_Obj), _STD forward<_Unbound>(_Unbargs)..., _STD get<_Ix>(_STD forward<_Cv_tuple_TiD>(_Tpl))...); } diff --git a/stl/inc/hash_map b/stl/inc/hash_map index 6675ac79037..e43b4099a76 100644 --- a/stl/inc/hash_map +++ b/stl/inc/hash_map @@ -59,11 +59,6 @@ namespace stdext { static constexpr bool _Has_transparent_overloads = false; -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ - _Hmap_traits() = default; _Hmap_traits(const _Tr& _Traits) noexcept(_STD is_nothrow_copy_constructible_v<_Tr>) : _Tr(_Traits) {} diff --git a/stl/inc/hash_set b/stl/inc/hash_set index 4aeabd0177b..676680998ed 100644 --- a/stl/inc/hash_set +++ b/stl/inc/hash_set @@ -54,11 +54,6 @@ namespace stdext { static constexpr bool _Has_transparent_overloads = false; -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ - _Hset_traits() = default; _Hset_traits(const _Tr& _Traits) noexcept(_STD is_nothrow_copy_constructible_v<_Tr>) : _Tr(_Traits) {} diff --git a/stl/inc/map b/stl/inc/map index 4e601e3a0b4..1e7c30bc404 100644 --- a/stl/inc/map +++ b/stl/inc/map @@ -387,12 +387,12 @@ map(initializer_list>, _Alloc) -> map<_Kty, _Ty, less<_Kty>, _Al template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, _Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>> requires (!_Allocator_for_container<_Pr>) -map(from_range_t, _Rng&&, _Pr = _Pr(), - _Alloc = _Alloc()) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; +map(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) + -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -map(from_range_t, _Rng&&, - _Alloc) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; +map(from_range_t, _Rng&&, _Alloc) + -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 @@ -601,8 +601,8 @@ public: #if _HAS_CXX17 template >, class _Alloc = allocator<_Guide_pair_t<_Iter>>, enable_if_t, negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0> -multimap( - _Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc()) -> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>; +multimap(_Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc()) + -> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>; template , class _Alloc = allocator>, enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> @@ -618,12 +618,12 @@ multimap(initializer_list>, _Alloc) -> multimap<_Kty, _Ty, less< template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, _Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>> requires (!_Allocator_for_container<_Pr>) -multimap(from_range_t, _Rng&&, _Pr = _Pr(), - _Alloc = _Alloc()) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; +multimap(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) + -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -multimap(from_range_t, _Rng&&, - _Alloc) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; +multimap(from_range_t, _Rng&&, _Alloc) + -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/mdspan b/stl/inc/mdspan index 3bb2292c5e2..99b6b7333bf 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -1463,17 +1463,17 @@ template mdspan(_ElementType*, const array<_OtherIndexType, _Nx>&) -> mdspan<_ElementType, dextents>; template -mdspan(_ElementType*, - const extents<_IndexType, _ExtentsPack...>&) -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>; +mdspan(_ElementType*, const extents<_IndexType, _ExtentsPack...>&) + -> mdspan<_ElementType, extents<_IndexType, _ExtentsPack...>>; template mdspan(_ElementType*, const _MappingType&) -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>; template -mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, - const _AccessorType&) -> mdspan; +mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, const _AccessorType&) + -> mdspan; _STD_END diff --git a/stl/inc/queue b/stl/inc/queue index b73b8cd1fa7..315033ad851 100644 --- a/stl/inc/queue +++ b/stl/inc/queue @@ -174,8 +174,8 @@ template <_Iterator_for_container _InIt, _Allocator_for_container _Alloc = alloc queue(_InIt, _InIt, _Alloc = _Alloc()) -> queue<_Iter_value_t<_InIt>, deque<_Iter_value_t<_InIt>, _Alloc>>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> -queue(from_range_t, _Rng&&, - _Alloc = _Alloc()) -> queue<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; +queue(from_range_t, _Rng&&, _Alloc = _Alloc()) + -> queue<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 _EXPORT_STD template @@ -450,8 +450,8 @@ priority_queue(_Pr, _Container) -> priority_queue>, class _Container = vector<_Iter_value_t<_Iter>>, enable_if_t, negation<_Is_allocator<_Pr>>, negation<_Is_allocator<_Container>>>, int> = 0> -priority_queue( - _Iter, _Iter, _Pr = _Pr(), _Container = _Container()) -> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>; +priority_queue(_Iter, _Iter, _Pr = _Pr(), _Container = _Container()) + -> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>; template >, negation<_Is_allocator<_Container>>, @@ -469,23 +469,23 @@ priority_queue(_Iter, _Iter, _Compare, _Alloc) -> priority_queue<_Iter_value_t<_ template , uses_allocator<_Container, _Alloc>>, int> = 0> -priority_queue(_Iter, _Iter, _Compare, _Container, - _Alloc) -> priority_queue; +priority_queue(_Iter, _Iter, _Compare, _Container, _Alloc) + -> priority_queue; #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>, enable_if_t::value, int> = 0> -priority_queue(from_range_t, _Rng&&, - _Pr = _Pr()) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>>, _Pr>; +priority_queue(from_range_t, _Rng&&, _Pr = _Pr()) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>>, _Pr>; template <_RANGES input_range _Rng, class _Pr, class _Alloc, enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> -priority_queue(from_range_t, _Rng&&, _Pr, - _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>, _Pr>; +priority_queue(from_range_t, _Rng&&, _Pr, _Alloc) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>, _Pr>; template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> -priority_queue(from_range_t, _Rng&&, - _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>>; +priority_queue(from_range_t, _Rng&&, _Alloc) + -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/ranges b/stl/inc/ranges index 49b69fa59e9..53da3d6daa2 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1025,8 +1025,8 @@ namespace ranges { }; template - requires (!_Integer_like<_Wi> || !_Integer_like<_Bo> - || (_Signed_integer_like<_Wi> == _Signed_integer_like<_Bo>) ) + requires ( + !_Integer_like<_Wi> || !_Integer_like<_Bo> || (_Signed_integer_like<_Wi> == _Signed_integer_like<_Bo>) ) iota_view(_Wi, _Bo) -> iota_view<_Wi, _Bo>; template @@ -3989,8 +3989,8 @@ namespace ranges { lazy_split_view(_Rng&&, _Pat&&) -> lazy_split_view, views::all_t<_Pat>>; template - lazy_split_view( - _Rng&&, range_value_t<_Rng>) -> lazy_split_view, single_view>>; + lazy_split_view(_Rng&&, range_value_t<_Rng>) + -> lazy_split_view, single_view>>; #if _HAS_CXX23 template @@ -7157,13 +7157,9 @@ namespace ranges { private: friend zip_view; -#if defined(__clang__) && __clang_major__ <= 18 // TRANSITION, Clang 19 (was thought to be LLVM-61763) - public: -#else // ^^^ workaround / no workaround vvv template requires _Zip_transform_constraints<_Func, _OtherViews...> friend class zip_transform_view; -#endif // ^^^ no workaround ^^^ using _My_tuple = tuple>...>; @@ -7982,13 +7978,9 @@ namespace ranges { private: friend adjacent_view; -#if defined(__clang__) && __clang_major__ <= 18 // TRANSITION, Clang 19 (was thought to be LLVM-61763) - public: -#else // ^^^ workaround / no workaround vvv template requires _Adjacent_transform_constraints<_Vw2, _Fn, _Nx2> friend class adjacent_transform_view; -#endif // ^^^ no workaround ^^^ using _Base = _Maybe_const<_Const, _Vw>; using _Base_iterator = iterator_t<_Base>; diff --git a/stl/inc/regex b/stl/inc/regex index e2805021159..5491b129ed0 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -334,8 +334,10 @@ public: template char_class_type lookup_classname(_Iter _First, _Iter _Last, bool _Icase = false) const { // map [_First, _Last) to character class mask value -#define _REGEX_CHAR_CLASS_NAME(n, c) \ - { n, L##n, static_cast(_STD size(n) - 1), c } +#define _REGEX_CHAR_CLASS_NAME(n, c) \ + { \ + n, L##n, static_cast(_STD size(n) - 1), c \ + } static constexpr _Cl_names _Names[] = { // map class names to numeric constants _REGEX_CHAR_CLASS_NAME("alnum", _Ch_alnum), diff --git a/stl/inc/set b/stl/inc/set index 5e049118ad4..d78a0b88cfb 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -415,8 +415,8 @@ template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng> multiset(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> multiset<_RANGES range_value_t<_Rng>, _Pr, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -multiset( - from_range_t, _Rng&&, _Alloc) -> multiset<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; +multiset(from_range_t, _Rng&&, _Alloc) + -> multiset<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 93d6422336d..7ba2935d369 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1659,8 +1659,8 @@ struct _Invoker_pmd_pointer { static constexpr _Invoker_strategy _Strategy = _Invoker_strategy::_Pmd_pointer; template - static constexpr auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) - noexcept(noexcept((*static_cast<_Ty1&&>(_Arg1)).*_Pmd)) -> decltype((*static_cast<_Ty1&&>(_Arg1)).*_Pmd) { + static constexpr auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) noexcept(noexcept((*static_cast<_Ty1&&>(_Arg1)).*_Pmd)) + -> decltype((*static_cast<_Ty1&&>(_Arg1)).*_Pmd) { return (*static_cast<_Ty1&&>(_Arg1)).*_Pmd; } }; @@ -1691,8 +1691,8 @@ template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, false> : _Invoker_functor {}; _EXPORT_STD template -constexpr auto invoke(_Callable&& _Obj) - noexcept(noexcept(static_cast<_Callable&&>(_Obj)())) -> decltype(static_cast<_Callable&&>(_Obj)()) { +constexpr auto invoke(_Callable&& _Obj) noexcept(noexcept(static_cast<_Callable&&>(_Obj)())) + -> decltype(static_cast<_Callable&&>(_Obj)()) { return static_cast<_Callable&&>(_Obj)(); } @@ -1912,12 +1912,12 @@ _EXPORT_STD template constexpr bool is_pointer_interconvertible_base_of_v = __is_pointer_interconvertible_base_of(_Base, _Derived); _EXPORT_STD template -_NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::*_Pm) noexcept { +_NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::* _Pm) noexcept { return __is_pointer_interconvertible_with_class(_ClassTy, _Pm); } _EXPORT_STD template -_NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::*_Pm1, _MemberTy2 _ClassTy2::*_Pm2) noexcept { +_NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::* _Pm1, _MemberTy2 _ClassTy2::* _Pm2) noexcept { return __is_corresponding_member(_ClassTy1, _ClassTy2, _Pm1, _Pm2); } #endif // ^^^ no workaround ^^^ diff --git a/stl/inc/unordered_map b/stl/inc/unordered_map index b8aff218ae4..b7f4891cf82 100644 --- a/stl/inc/unordered_map +++ b/stl/inc/unordered_map @@ -461,8 +461,8 @@ template >, class _Keyeq = enable_if_t< conjunction_v<_Is_iterator<_Iter>, _Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), - _Alloc = _Alloc()) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, _Keyeq, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) + -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, _Keyeq, _Alloc>; template , class _Keyeq = equal_to<_Kty>, class _Alloc = allocator>, @@ -472,30 +472,29 @@ unordered_map(initializer_list>, _Guide_size_type_t<_Alloc> = 0, template , _Is_allocator<_Alloc>>, int> = 0> unordered_map(_Iter, _Iter, _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, - hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; + hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, - equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_map<_Guide_key_t<_Iter>, + _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_map(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_map( - initializer_list>, _Alloc) -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Alloc) + -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template ::value, int> = 0> -unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_map<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_map<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_map<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>, @@ -506,13 +505,12 @@ unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _H _Alloc = _Alloc()) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_map<_Range_key_type<_Rng>, + _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, - hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; + hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) @@ -844,12 +842,11 @@ unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc> template , _Is_allocator<_Alloc>>, int> = 0> unordered_multimap(_Iter, _Iter, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, - hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; + hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, - equal_to<_Guide_key_t<_Iter>>, _Alloc>; +unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, + _Guide_val_t<_Iter>, hash<_Guide_key_t<_Iter>>, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> @@ -857,17 +854,17 @@ unordered_multimap(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Hasher, equal_to<_Guide_key_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_multimap( - initializer_list>, _Alloc) -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Alloc) + -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template ::value, int> = 0> -unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multimap<_Kty, _Ty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multimap<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multimap<_Kty, _Ty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>, @@ -878,19 +875,18 @@ unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher _Alloc = _Alloc()) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, + equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multimap( - from_range_t, _Rng&&, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, - hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, + hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, - equal_to<_Range_key_type<_Rng>>, _Alloc>; +unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, equal_to<_Range_key_type<_Rng>>, + _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index 7e49770386f..0f41d148e97 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -326,8 +326,8 @@ template >, class _Keyeq enable_if_t< conjunction_v<_Is_iterator<_Iter>, _Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), - _Alloc = _Alloc()) -> unordered_set<_Iter_value_t<_Iter>, _Hasher, _Keyeq, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) + -> unordered_set<_Iter_value_t<_Iter>, _Hasher, _Keyeq, _Alloc>; template , class _Keyeq = equal_to<_Kty>, class _Alloc = allocator<_Kty>, enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> @@ -335,22 +335,22 @@ unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Alloc = _Alloc()) -> unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_Iter_value_t<_Iter>, hash<_Iter_value_t<_Iter>>, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_set<_Iter_value_t<_Iter>, hash<_Iter_value_t<_Iter>>, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_set(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_set<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>, @@ -361,18 +361,16 @@ unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _H _Alloc = _Alloc()) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_set( - from_range_t, _Rng&&, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 @@ -685,17 +683,17 @@ unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Alloc) template , _Is_hasher<_Hasher>, _Is_allocator<_Alloc>>, int> = 0> -unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; +unordered_multiset(_Iter, _Iter, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_Iter_value_t<_Iter>, _Hasher, equal_to<_Iter_value_t<_Iter>>, _Alloc>; template ::value, int> = 0> -unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multiset<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; +unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multiset<_Kty, hash<_Kty>, equal_to<_Kty>, _Alloc>; template , _Is_allocator<_Alloc>>, int> = 0> -unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; +unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_Kty, _Hasher, equal_to<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>, @@ -706,18 +704,17 @@ unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher _Alloc = _Alloc()) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, - _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) + -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, + equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> -unordered_multiset( - from_range_t, _Rng&&, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, - equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, + hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> -unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, - _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; +unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) + -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/utility b/stl/inc/utility index 4fc04c67f4f..ae7f4094f14 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -319,7 +319,7 @@ struct pair { // store a pair of values is_constructible<_Ty2, decltype(_STD get<1>(_STD declval<_Other>()))>> #endif // ^^^ no workaround ^^^ constexpr explicit(!conjunction_v(_STD declval<_Other>())), _Ty1>, - is_convertible(_STD declval<_Other>())), _Ty2>>) pair(_Other&& _Right) + is_convertible(_STD declval<_Other>())), _Ty2>>) pair(_Other&& _Right) noexcept(is_nothrow_constructible_v<_Ty1, decltype(_STD get<0>(_STD declval<_Other>()))> && is_nothrow_constructible_v<_Ty2, decltype(_STD get<1>(_STD declval<_Other>()))>) // strengthened : first(_STD get<0>(_STD forward<_Other>(_Right))), second(_STD get<1>(_STD forward<_Other>(_Right))) { diff --git a/stl/inc/variant b/stl/inc/variant index ac38081fe06..8d472e9ca24 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -499,17 +499,14 @@ _NODISCARD constexpr decltype(auto) _Variant_raw_get(_Storage&& _Obj) noexcept { return _STD _Variant_raw_get<_Idx - 8>( static_cast<_Storage&&>(_Obj)._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else if constexpr (_Idx < 32) { - return _STD _Variant_raw_get<_Idx - 16>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 16>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else if constexpr (_Idx < 64) { - return _STD _Variant_raw_get<_Idx - 32>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 32>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail); } else { // _Idx >= 64 - return _STD _Variant_raw_get<_Idx - 64>( - static_cast<_Storage&&>(_Obj) + return _STD _Variant_raw_get<_Idx - 64>(static_cast<_Storage&&>(_Obj) ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail ._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail diff --git a/stl/inc/xhash b/stl/inc/xhash index 617138b038b..0df519a86ff 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -97,11 +97,6 @@ template struct _Uhash_choose_transparency { // transparency selector for non-transparent hashed containers static constexpr bool _Has_transparent_overloads = false; - -#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753 - template - static constexpr bool _Supports_transparency = false; -#endif // ^^^ workaround ^^^ }; #if _HAS_CXX20 diff --git a/stl/inc/xlocale b/stl/inc/xlocale index ed2f61f1c2d..77c8d1b4c9b 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -28,6 +28,7 @@ class _Locbase {}; // TRANSITION, ABI, affects sizeof(locale) _EXPORT_STD template class collate; +// clang-format off: clang-format 19 doesn't understand _CRTIMP2_PURE_IMPORT and will poorly format the following code extern "C++" struct _CRTIMP2_PURE_IMPORT _Crt_new_delete { // base class for marking allocations as CRT blocks #ifdef _DEBUG void* __CLRCALL_OR_CDECL operator new(size_t _Size) { // replace operator new @@ -58,6 +59,7 @@ extern "C++" struct _CRTIMP2_PURE_IMPORT _Crt_new_delete { // base class for mar void __CLRCALL_OR_CDECL operator delete(void*, void*) noexcept {} // imitate True Placement Delete #endif // _DEBUG }; +// clang-format on _EXPORT_STD extern "C++" class locale : public _Locbase, public _Crt_new_delete { public: diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 36682328eb6..5cf765bec5d 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -878,7 +878,7 @@ private: const size_t _Offset_digit_end = _Parse_hex ? _Offset_hex_digit_end : _Offset_dec_digit_end; if (_Grouping.empty()) { for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Significant >= _Max_sig_dig) { ++_Power_of_rep_base; // just scale by 10 or 16 if (_Idx > 0) { @@ -977,7 +977,7 @@ private: } for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Significant < _Max_sig_dig) { // save a significant fraction digit *_Ptr++ = _Src[_Idx]; ++_Significant; @@ -1018,7 +1018,7 @@ private: } for (size_t _Idx; _First != _Last && (_Idx = _STD _Find_elem(_Atoms, *_First)) < _Offset_dec_digit_end; - _Seendigit = true, (void) ++_First) { + _Seendigit = true, (void) ++_First) { if (_Exponent_part < PTRDIFF_MAX / 10 || (_Exponent_part == PTRDIFF_MAX / 10 && static_cast(_Idx) <= PTRDIFF_MAX % 10)) { // save a significant exponent digit @@ -1091,7 +1091,7 @@ private: char* const _Rev_begin = _Ptr; for (ptrdiff_t _Exponent_part_abs = _STD abs(_Exponent_part); _Exponent_part_abs != 0; - _Exponent_part_abs /= 10) { + _Exponent_part_abs /= 10) { *_Ptr++ = static_cast('0' + _Exponent_part_abs % 10); } _STD reverse(_Rev_begin, _Ptr); diff --git a/stl/inc/xloctime b/stl/inc/xloctime index b48e1b1d25f..9534cdefddf 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -55,8 +55,8 @@ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& } for (char* const _Pe = &_Ac[_Max_int_dig - 1]; - _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits; - ++_Digits_read, (void) ++_First) { // copy digits + _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits; + ++_Digits_read, (void) ++_First) { // copy digits *_Ptr = _Ch; if (_Ptr < _Pe) { ++_Ptr; // drop trailing digits if already too large diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 462a7465fc5..7567d415a15 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -1663,7 +1663,9 @@ _NoThrowFwdIt _Uninitialized_move_unchecked(_InIt _First, const _InIt _Last, _No #if 0 // TRANSITION, _HAS_CXX26 if (!_STD is_constant_evaluated()) #endif // _HAS_CXX26 - { return _STD _Copy_memmove(_First, _Last, _Dest); } + { + return _STD _Copy_memmove(_First, _Last, _Dest); + } } _Uninitialized_backout<_NoThrowFwdIt> _Backout{_Dest}; for (; _First != _Last; ++_First) { @@ -1934,7 +1936,9 @@ _NoThrowFwdIt _Uninitialized_copy_unchecked(_InIt _First, const _InIt _Last, _No #if 0 // TRANSITION, _HAS_CXX26 if (!_STD is_constant_evaluated()) #endif // _HAS_CXX26 - { return _STD _Copy_memmove(_First, _Last, _Dest); } + { + return _STD _Copy_memmove(_First, _Last, _Dest); + } } _Uninitialized_backout<_NoThrowFwdIt> _Backout{_Dest}; diff --git a/stl/inc/xstring b/stl/inc/xstring index 55b5a67de10..ea4393dae3d 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3083,13 +3083,13 @@ private: #if _HAS_CXX17 template >, enable_if_t, _Is_allocator<_Alloc>>, int> = 0> -basic_string( - _Iter, _Iter, _Alloc = _Alloc()) -> basic_string<_Iter_value_t<_Iter>, char_traits<_Iter_value_t<_Iter>>, _Alloc>; +basic_string(_Iter, _Iter, _Alloc = _Alloc()) + -> basic_string<_Iter_value_t<_Iter>, char_traits<_Iter_value_t<_Iter>>, _Alloc>; template , enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> -explicit basic_string( - basic_string_view<_Elem, _Traits>, const _Alloc& = _Alloc()) -> basic_string<_Elem, _Traits, _Alloc>; +explicit basic_string(basic_string_view<_Elem, _Traits>, const _Alloc& = _Alloc()) + -> basic_string<_Elem, _Traits, _Alloc>; template , enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> @@ -3098,8 +3098,8 @@ basic_string(basic_string_view<_Elem, _Traits>, _Guide_size_type_t<_Alloc>, _Gui #if _HAS_CXX23 template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> -basic_string(from_range_t, _Rng&&, - _Alloc = _Alloc()) -> basic_string<_RANGES range_value_t<_Rng>, char_traits<_RANGES range_value_t<_Rng>>, _Alloc>; +basic_string(from_range_t, _Rng&&, _Alloc = _Alloc()) + -> basic_string<_RANGES range_value_t<_Rng>, char_traits<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 diff --git a/stl/inc/xutility b/stl/inc/xutility index 3a0592c74c6..d31e7079341 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2033,14 +2033,14 @@ _NODISCARD constexpr _Ty* end(_Ty (&_Array)[_Size]) noexcept { } _EXPORT_STD template -_NODISCARD constexpr auto cbegin(const _Container& _Cont) - noexcept(noexcept(_STD begin(_Cont))) -> decltype(_STD begin(_Cont)) { +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) + -> decltype(_STD begin(_Cont)) { return _STD begin(_Cont); } _EXPORT_STD template -_NODISCARD constexpr auto cend(const _Container& _Cont) - noexcept(noexcept(_STD end(_Cont))) -> decltype(_STD end(_Cont)) { +_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) + -> decltype(_STD end(_Cont)) { return _STD end(_Cont); } @@ -4123,10 +4123,9 @@ namespace ranges { subrange(_It, _Se, _Make_unsigned_like_t>) -> subrange<_It, _Se, subrange_kind::sized>; template - subrange(_Rng&&) - -> subrange, sentinel_t<_Rng>, - (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized - : subrange_kind::unsized>; + subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, + (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized + : subrange_kind::unsized>; template subrange(_Rng&&, _Make_unsigned_like_t>) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 01c8c4187ce..93472f700b6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -929,8 +929,8 @@ _EMIT_STL_ERROR(STL1002, "Unexpected compiler version, expected CUDA 12.4 or new #elif defined(__EDG__) // not attempting to detect __EDG_VERSION__ being less than expected #elif defined(__clang__) -#if __clang_major__ < 18 -_EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 18.0.0 or newer."); +#if __clang_major__ < 19 +_EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 19.0.0 or newer."); #endif // ^^^ old Clang ^^^ #elif defined(_MSC_VER) #if _MSC_VER < 1942 // Coarse-grained, not inspecting _MSC_FULL_VER diff --git a/stl/src/excptptr.cpp b/stl/src/excptptr.cpp index 830cb65a940..e866980fb1d 100644 --- a/stl/src/excptptr.cpp +++ b/stl/src/excptptr.cpp @@ -505,8 +505,10 @@ _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(void* // Alloc memory on stack for exception object. This might cause a stack overflow SEH exception, or another C++ // exception when copying the C++ exception object. In that case, we just let that become the thrown exception. -#pragma warning(suppress : 6255) // _alloca indicates failure by raising a stack overflow exception +#pragma warning(push) +#pragma warning(disable : 6255) // _alloca indicates failure by raising a stack overflow exception void* _PExceptionBuffer = alloca(_PType->sizeOrOffset); +#pragma warning(pop) _CopyExceptionObject(_PExceptionBuffer, _CppRecord.params.pExceptionObject, _PType #if _EH_RELATIVE_TYPEINFO , diff --git a/stl/src/locale.cpp b/stl/src/locale.cpp index 8dc8f4a1f07..e11e106f16f 100644 --- a/stl/src/locale.cpp +++ b/stl/src/locale.cpp @@ -124,8 +124,10 @@ void __CLRCALL_PURE_OR_CDECL locale::_Locimp::_Locimp_Addfac( } } ptrfac->_Incref(); -#pragma warning(suppress : 6001) // PREfast isn't following through _realloc_crt here +#pragma warning(push) +#pragma warning(disable : 6001) // PREfast isn't following through _realloc_crt here if (_This->_Facetvec[id] != nullptr) { +#pragma warning(pop) delete _This->_Facetvec[id]->_Decref(); } diff --git a/stl/src/multprec.cpp b/stl/src/multprec.cpp index 6236e33b624..0043cfbfb96 100644 --- a/stl/src/multprec.cpp +++ b/stl/src/multprec.cpp @@ -134,8 +134,10 @@ void __CLRCALL_PURE_OR_CDECL _MP_Rem( unsigned long long rh = ((u[j + n] << shift) + u[j + n - 1]) % v[n - 1]; for (;;) { -#pragma warning(suppress : 6385) // TRANSITION, GH-1008 +#pragma warning(push) +#pragma warning(disable : 6385) // TRANSITION, GH-1008 if (qh < maxVal && qh * v[n - 2] <= (rh << shift) + u[j + n - 2]) { +#pragma warning(pop) break; } else { // reduce tentative value and retry --qh; diff --git a/stl/src/xstoul.cpp b/stl/src/xstoul.cpp index 50789659027..02db3d9394f 100644 --- a/stl/src/xstoul.cpp +++ b/stl/src/xstoul.cpp @@ -71,7 +71,7 @@ _CRTIMP2_PURE unsigned long __CLRCALL_PURE_OR_CDECL _Stoulx( x = 0; for (s2 = sc, y = 0; (sd = static_cast(memchr(&digits[0], tolower(*sc), base))) != nullptr; - ++sc) { // accumulate digits + ++sc) { // accumulate digits y = x; dig = static_cast(sd - digits); // for overflow checking x = x * base + dig; diff --git a/stl/src/xstoull.cpp b/stl/src/xstoull.cpp index 5d058e9d025..88aff9b076c 100644 --- a/stl/src/xstoull.cpp +++ b/stl/src/xstoull.cpp @@ -69,7 +69,7 @@ _CRTIMP2_PURE unsigned long long __CLRCALL_PURE_OR_CDECL _Stoullx( x = 0; for (s2 = sc, y = 0, dig = 0; (sd = static_cast(memchr(&digits[0], tolower(*sc), base))) != nullptr; - ++sc) { // accumulate digits + ++sc) { // accumulate digits y = x; dig = static_cast(sd - digits); // for overflow checking x = x * base + dig; diff --git a/stl/src/xwcsxfrm.cpp b/stl/src/xwcsxfrm.cpp index 417545e1f85..f3a2300dac3 100644 --- a/stl/src/xwcsxfrm.cpp +++ b/stl/src/xwcsxfrm.cpp @@ -73,9 +73,11 @@ _CRTIMP2_PURE size_t __CLRCALL_PURE_OR_CDECL _Wcsxfrm(_Out_writes_(end1 - string auto bbuffer = _malloc_crt_t(unsigned char, n1); if (bbuffer) { -#pragma warning(suppress : 6386) // PREfast doesn't understand LCMAP_SORTKEY +#pragma warning(push) +#pragma warning(disable : 6386) // PREfast doesn't understand LCMAP_SORTKEY size = __crtLCMapStringW(locale_name, LCMAP_SORTKEY, string2, static_cast(n2), reinterpret_cast(bbuffer.get()), static_cast(n1)); +#pragma warning(pop) if (size == 0) { // buffer not big enough, get size required. diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 1f09a82fe49..52c4877f626 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -173,7 +173,7 @@ std/ranges/range.adaptors/range.join/range.join.iterator/arrow.pass.cpp FAIL std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp FAIL -# *** INTERACTIONS WITH CONTEST / C1XX THAT UPSTREAM LIKELY WON'T FIX *** +# *** INTERACTIONS WITH MSVC THAT UPSTREAM LIKELY WON'T FIX *** # These tests set an allocator with a max_size() too small to default construct an unordered container # (due to our minimum bucket size). std/containers/unord/unord.map/max_size.pass.cpp FAIL @@ -428,16 +428,76 @@ std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp:1 FAIL std/language.support/support.rtti/type.info/type_info.equal.pass.cpp:0 FAIL std/language.support/support.rtti/type.info/type_info.equal.pass.cpp:1 FAIL +# DevCom-10808176 VSO-2319111 MSVC doesn't properly destroy a loop variable in constant evaluation +# Fixed in VS 2022 17.14 Preview 1. +std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:0 FAIL +std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size_value.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size_value.pass.cpp:1 FAIL +std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector/reverse_iterators.pass.cpp:0 FAIL +std/containers/sequences/vector/reverse_iterators.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:1 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:0 FAIL +std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:1 FAIL +std/containers/views/mdspan/mdspan/index_operator.pass.cpp:0 FAIL +std/containers/views/mdspan/mdspan/index_operator.pass.cpp:1 FAIL + +# VSO-2338829 constexpr error "subtracting pointers to elements of different arrays" in _String_const_iterator::_Verify_offset() +std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:1 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:0 FAIL +std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:1 FAIL + +# VSO-2338880 constexpr error in vector::iterator's _Compat() check when using views::transform +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:1 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:0 FAIL +std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:1 FAIL + # *** CLANG COMPILER BUGS *** # LLVM-46207 Clang's tgmath.h interferes with the UCRT's tgmath.h std/depr/depr.c.headers/tgmath_h.pass.cpp:2 FAIL -# LLVM-95311 [clang] __has_unique_object_representations gives inconsistent answer based on instantiation order -# A libc++ product code workaround (using `remove_all_extents_t`) and test coverage were added by LLVM-95314. -# Fixed by LLVM-95432 in Clang 19. -std/utilities/meta/meta.unary/meta.unary.prop/has_unique_object_representations.compile.pass.cpp:2 FAIL - # *** CLANG ISSUES, NOT YET ANALYZED *** # Not analyzed. Clang apparently defines platform macros differently from C1XX. @@ -447,10 +507,6 @@ std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp:2 FAIL std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp:2 FAIL -# Not analyzed. __cpp_sized_deallocation isn't being defined by Clang. -std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp:2 FAIL -std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp:2 FAIL - # *** STL BUGS *** # GH-784 : aligned_storage has incorrect alignment defaults @@ -533,6 +589,7 @@ std/input.output/syncstream/syncbuf/syncstream.syncbuf.members/emit.pass.cpp FAI # *** VCRUNTIME BUGS *** # DevCom-10373274 VSO-1824997 "vcruntime nothrow array operator new falls back on the wrong function" # This passes for the :1 (ASan) configuration, surprisingly. +# Fixed in VS 2022 17.14 Preview 1. std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp:0 FAIL std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp:2 FAIL @@ -889,35 +946,6 @@ std/algorithms/algorithms.results/min_max_result.pass.cpp:1 FAIL # Not analyzed. std/algorithms/robust_against_proxy_iterators_lifetime_bugs.pass.cpp FAIL -# Not analyzed. Possible MSVC constexpr bug. -# note: failure was caused by a read of a variable outside its lifetime -std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:0 FAIL -std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size_value.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size_value.pass.cpp:1 FAIL -std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector/reverse_iterators.pass.cpp:0 FAIL -std/containers/sequences/vector/reverse_iterators.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp:1 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:0 FAIL -std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp:1 FAIL -std/containers/views/mdspan/mdspan/index_operator.pass.cpp:0 FAIL -std/containers/views/mdspan/mdspan/index_operator.pass.cpp:1 FAIL - # Not analyzed. Looks like a test bug, assuming that hash> is constexpr. std/containers/sequences/vector.bool/enabled_hash.pass.cpp FAIL std/containers/sequences/vector.bool/vector_bool.pass.cpp FAIL @@ -949,28 +977,6 @@ std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/iter_swap.pass # Clang error: non-type template argument is not a constant expression std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_const_move.pass.cpp FAIL -# Not analyzed, probably MSVC constexpr issue(s) -std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp:1 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:0 FAIL -std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp:1 FAIL - # Not analyzed, possible path length issue. With a repo root of D:\GitHub\STL (13 characters), fails with: # "error RC2136 : missing '=' in EXSTYLE=" followed by "LINK : fatal error LNK1327: failure during running rc.exe" std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp SKIPPED @@ -1074,20 +1080,6 @@ std/time/time.syn/formatter.local_time.pass.cpp:2 FAIL std/time/time.syn/formatter.sys_time.pass.cpp:2 FAIL std/time/time.syn/formatter.zoned_time.pass.cpp:2 FAIL -# Not analyzed. constexpr evaluation fails with "vector iterators incompatible". -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.segmented.pass.cpp:1 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:0 FAIL -std/algorithms/alg.modifying.operations/alg.move/ranges.move.segmented.pass.cpp:1 FAIL - # Not analyzed. constexpr evaluation fails with note: failure was caused by out of range index MEOW; allowed range is 0 <= index < 2 std/ranges/range.adaptors/range.join/adaptor.pass.cpp:0 FAIL std/ranges/range.adaptors/range.join/adaptor.pass.cpp:1 FAIL @@ -1346,6 +1338,14 @@ std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.fold/left_folds.pass.cpp:9 SKIPPED +std/containers/associative/map/map.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/multimap/multimap.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/multiset/insert_range.pass.cpp:9 SKIPPED +std/containers/associative/set/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.multiset/insert_range.pass.cpp:9 SKIPPED +std/containers/unord/unord.set/insert_range.pass.cpp:9 SKIPPED std/depr/depr.c.headers/setjmp_h.compile.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp:9 SKIPPED @@ -1356,17 +1356,6 @@ std/ranges/range.utility/range.utility.conv/to.pass.cpp:9 SKIPPED std/thread/thread.jthread/assign.move.pass.cpp:9 SKIPPED std/utilities/meta/meta.unary/dependent_return_type.compile.pass.cpp:9 SKIPPED -# These tests also need ADDITIONAL_COMPILE_FLAGS to silence warnings, but only for Clang 18. -# TRANSITION, Clang 19 -std/containers/associative/map/map.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/multimap/multimap.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/multiset/insert_range.pass.cpp:9 SKIPPED -std/containers/associative/set/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.multiset/insert_range.pass.cpp:9 SKIPPED -std/containers/unord/unord.set/insert_range.pass.cpp:9 SKIPPED - # This test is marked as `XFAIL: msvc`, but the MSVC-internal test harness doesn't yet parse XFAIL. std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp:9 SKIPPED diff --git a/tests/std/include/instantiate_algorithms_op_deref.hpp b/tests/std/include/instantiate_algorithms_op_deref.hpp index 43ab47a2a4e..1d5a22656e8 100644 --- a/tests/std/include/instantiate_algorithms_op_deref.hpp +++ b/tests/std/include/instantiate_algorithms_op_deref.hpp @@ -333,7 +333,9 @@ void test_optional() { const optional oe{Evil()}; (void) oe.value(); } - { (void) optional{Evil()}.value(); } + { + (void) optional{Evil()}.value(); + } { using T = const optional; (void) T{Evil()}.value(); diff --git a/tests/std/tests/Dev08_563686_ostream/test.cpp b/tests/std/tests/Dev08_563686_ostream/test.cpp index 11d905320fd..73b7cc3cca5 100644 --- a/tests/std/tests/Dev08_563686_ostream/test.cpp +++ b/tests/std/tests/Dev08_563686_ostream/test.cpp @@ -49,7 +49,9 @@ int main() { _CrtMemCheckpoint(&before); // Construct and destroy an iostream, which previously leaked. - { std::iostream s(nullptr); } + { + std::iostream s(nullptr); + } // Get memory state after iostream allocation/deallocation _CrtMemState after; diff --git a/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp b/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp index b8f0fa0309a..4d9f52562ba 100644 --- a/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp +++ b/tests/std/tests/Dev09_126254_persistent_aux_allocators/test.cpp @@ -98,10 +98,12 @@ void dump_map() { } } +#pragma warning(push) +#pragma warning(disable : 4324) // structure was padded due to alignment specifier struct alignas(64) OverAlignedInt { int x; -#pragma warning(suppress : 4324) // structure was padded due to alignment specifier }; +#pragma warning(pop) void test_gh_2362() { // GH-2362 suggests to add a debug-only nullptr assertion inside std::allocator::deallocate, checking diff --git a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp index 0187f23f355..fcfcc11bea1 100644 --- a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp +++ b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp @@ -200,7 +200,7 @@ STATIC_ASSERT(is_function_v); // non-viable.) template -int use_mem_fn(R Cat::*pmf) { +int use_mem_fn(R Cat::* pmf) { Cat cat; return mem_fn(pmf)(cat); } diff --git a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp index f74e3eaefcf..1dfa529bc83 100644 --- a/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp +++ b/tests/std/tests/Dev09_173612_tr1_regex_leak/test.cpp @@ -157,7 +157,9 @@ void test(const char* s) { const int orig_scalars = g_scalars; const int orig_arrays = g_arrays; - { regex r(s); } + { + regex r(s); + } if (g_scalars != orig_scalars) { printf("test(): %d scalar allocation leak(s)!\n", g_scalars - orig_scalars); diff --git a/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp b/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp index 8d18750ea3f..91fb0f1d9c1 100644 --- a/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp +++ b/tests/std/tests/Dev10_491486_floating_point_hash/test.cpp @@ -29,8 +29,10 @@ void test_case() { assert(fake_bit_cast(pos0d) == 0); const auto neg0d = static_cast(0.0 * -1.0); assert(fake_bit_cast(neg0d) == topBitSet); -#pragma warning(suppress : 6326) // potential comparison of a constant with another constant +#pragma warning(push) +#pragma warning(disable : 6326) // potential comparison of a constant with another constant assert(pos0d == neg0d); +#pragma warning(pop) assert(hash()(pos0d) == hash()(neg0d)); array a{{ diff --git a/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp b/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp index 159da7d9d99..99952f17f12 100644 --- a/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp +++ b/tests/std/tests/Dev10_561430_list_and_tree_leaks/test.cpp @@ -116,9 +116,13 @@ int main() { } #endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT - { shared_ptr sp(new int(1729), default_delete(), Mallocator()); } + { + shared_ptr sp(new int(1729), default_delete(), Mallocator()); + } - { shared_ptr sp = allocate_shared(Mallocator(), 1729); } + { + shared_ptr sp = allocate_shared(Mallocator(), 1729); + } #ifndef _M_CEE_PURE { diff --git a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp index 492030269dc..cc2fabe66af 100644 --- a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp +++ b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp @@ -1017,7 +1017,7 @@ void test_reference_wrapper_invocation() { pmf = &Thing::product; assert(rw_pmf(sp, 3) == 60000); - int Thing::*pmd = &Thing::m_x; + int Thing::* pmd = &Thing::m_x; reference_wrapper rw_pmd(pmd); assert(rw_pmd(*sp) == 1000); assert(rw_pmd(sp.get()) == 1000); diff --git a/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp b/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp index 16ae8abdb4b..1b528030f81 100644 --- a/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp +++ b/tests/std/tests/Dev11_0617384_empty_std_function/test.cpp @@ -35,7 +35,7 @@ int main() { #endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT int (X::*pmf)(int) = nullptr; - int X::*pmd = nullptr; + int X::* pmd = nullptr; assert(!function(pmf)); assert(!function(pmd)); diff --git a/tests/std/tests/Dev11_0836436_get_time/test.cpp b/tests/std/tests/Dev11_0836436_get_time/test.cpp index 6c05df8bd3f..ff7a8be5b97 100644 --- a/tests/std/tests/Dev11_0836436_get_time/test.cpp +++ b/tests/std/tests/Dev11_0836436_get_time/test.cpp @@ -912,7 +912,7 @@ void test_gh_4820() { void test_gh_4882() { // GH-4882 : std::put_time should not crash on invalid/out-of-range tm struct values - const auto fieldValidation = [](int tm::*const field, const int value, const string& fmt) { + const auto fieldValidation = [](int tm::* const field, const int value, const string& fmt) { time_t t = time(nullptr); tm currentTime; localtime_s(¤tTime, &t); @@ -939,7 +939,7 @@ void test_gh_4882() { }; struct FormatTestData { - int tm::*field; + int tm::* field; int lo; int hi; string fmt; diff --git a/tests/std/tests/GH_001858_iostream_exception/test.cpp b/tests/std/tests/GH_001858_iostream_exception/test.cpp index 7c23e0ff118..eaec61efee0 100644 --- a/tests/std/tests/GH_001858_iostream_exception/test.cpp +++ b/tests/std/tests/GH_001858_iostream_exception/test.cpp @@ -619,15 +619,15 @@ STATIC_ASSERT( STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_istringstream, pmr::polymorphic_allocator>>); + basic_istringstream, pmr::polymorphic_allocator>>); STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_ostringstream, pmr::polymorphic_allocator>>); + basic_ostringstream, pmr::polymorphic_allocator>>); STATIC_ASSERT( !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); STATIC_ASSERT(!is_nothrow_move_assignable_v< - basic_stringstream, pmr::polymorphic_allocator>>); + basic_stringstream, pmr::polymorphic_allocator>>); #endif // _HAS_CXX17 STATIC_ASSERT(is_nothrow_std_swappable); diff --git a/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp index 4dff687801e..4fbb07e70f9 100644 --- a/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp +++ b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp @@ -23,8 +23,8 @@ static_assert(contiguous_iterator); static_assert(contiguous_iterator); static_assert(contiguous_iterator); static_assert(contiguous_iterator); -static_assert(contiguous_iterator); -static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); // Tests for move_iterator specializations static_assert(random_access_iterator>); @@ -39,5 +39,5 @@ static_assert(random_access_iterator>); static_assert(random_access_iterator>); static_assert(random_access_iterator>); static_assert(random_access_iterator>); -static_assert(random_access_iterator>); -static_assert(random_access_iterator>); +static_assert(random_access_iterator>); +static_assert(random_access_iterator>); diff --git a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp index d1bdbdfa72b..b26ca701f86 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp @@ -204,7 +204,7 @@ constexpr void check_construction_from_other_left_mapping() { { // Check implicit conversions static_assert(!NotImplicitlyConstructibleFrom>, - layout_left::mapping>>); + layout_left::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, layout_left::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, diff --git a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp index 75c685c3e92..89899ab408c 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp @@ -203,7 +203,7 @@ constexpr void check_construction_from_other_right_mapping() { { // Check implicit conversions static_assert(!NotImplicitlyConstructibleFrom>, - layout_right::mapping>>); + layout_right::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, layout_right::mapping>>); static_assert(NotImplicitlyConstructibleFrom>, diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 033b68fc761..f2dadd09de6 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -353,11 +353,11 @@ constexpr void check_construction_from_other_mappings() { static_assert(!is_constructible_v>>); static_assert(!is_constructible_v>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); static_assert(!is_constructible_v::mapping>>); + LyingLayout::mapping>>); } { // Check construction from layout_left::mapping @@ -540,13 +540,13 @@ constexpr void check_comparisons() { static_assert(!equality_comparable_with>>); static_assert(!equality_comparable_with>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); static_assert(!equality_comparable_with::mapping>>); + LyingLayout::mapping>>); } { // Check correctness: layout_stride::mapping with layout_stride::mapping diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index 8a682080e90..330d3cadc34 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -602,9 +602,9 @@ constexpr void check_data_handle_and_span_array_constructors() { static_assert(is_nothrow_constructible_v, layout_right, VectorBoolAccessor>, vector::iterator, array>); // strengthened static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - span>); + span>); static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - array>); + array>); } { // Check explicitness @@ -689,9 +689,9 @@ constexpr void check_data_handle_and_extents_constructor() { static_assert(is_nothrow_constructible_v, layout_right, VectorBoolAccessor>, vector::iterator, extents>); // strengthened static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - dextents>); + dextents>); static_assert(!is_constructible_v, layout_right, TrackingAccessor>, int*, - extents>); + extents>); } { // Check effects: 'direct-non-list-initializes ptr_ with std::move(p)' @@ -722,11 +722,11 @@ constexpr void check_data_handle_and_mapping_constructor() { static_assert(is_nothrow_constructible_v, layout_left>, int* const, layout_left::mapping>>); // strengthened static_assert(!is_constructible_v< - mdspan, extents, TrackingLayout<>, TrackingAccessor>>, - vector*, TrackingLayout<>::mapping>>); + mdspan, extents, TrackingLayout<>, TrackingAccessor>>, vector*, + TrackingLayout<>::mapping>>); static_assert(!is_constructible_v< - mdspan, extents, TrackingLayout<>, TrackingAccessor>>, - deque* const, TrackingLayout<>::mapping>>); + mdspan, extents, TrackingLayout<>, TrackingAccessor>>, + deque* const, TrackingLayout<>::mapping>>); } { // Check effect: 'direct-non-list-initializes ptr_ with std::move(p)' @@ -781,7 +781,7 @@ constexpr void check_data_handle_and_mapping_and_accessor_constructor() { using Mds2 = mdspan, TrackingLayout<>>; static_assert(!is_nothrow_constructible_v); + const Mds2::accessor_type&>); } } @@ -791,9 +791,9 @@ constexpr void check_construction_from_other_mdspan() { static_assert(is_nothrow_constructible_v, layout_stride>, mdspan, layout_right>>); // strengthened static_assert(!is_constructible_v, layout_left>, - mdspan, layout_right>>); + mdspan, layout_right>>); static_assert(!is_constructible_v, layout_left>, - mdspan, layout_left>>); + mdspan, layout_left>>); } { // Check constraint: 'is_constructible_v' @@ -802,7 +802,7 @@ constexpr void check_construction_from_other_mdspan() { is_nothrow_constructible_v>, mdspan>>); // strengthened static_assert(!is_constructible_v>, - mdspan>>); + mdspan>>); } { // Check explicitness @@ -810,13 +810,13 @@ constexpr void check_construction_from_other_mdspan() { static_assert(NotImplicitlyConstructibleFrom, layout_left>, mdspan, layout_stride>>); static_assert(!NotImplicitlyConstructibleFrom, layout_stride>, - mdspan, layout_left>>); + mdspan, layout_left>>); static_assert(NotImplicitlyConstructibleFrom< mdspan, layout_left, AccessorWithCustomOffsetPolicy>, mdspan, layout_left, AccessorWithCustomOffsetPolicy>>); static_assert(!NotImplicitlyConstructibleFrom< - mdspan, layout_left, default_accessor>, - mdspan, layout_left, default_accessor>>); + mdspan, layout_left, default_accessor>, + mdspan, layout_left, default_accessor>>); } { // Check effects diff --git a/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp b/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp index a8f06f3af5a..c44d96a4ac9 100644 --- a/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp +++ b/tests/std/tests/P0053R7_cpp_synchronized_buffered_ostream/test.cpp @@ -348,7 +348,9 @@ void test_osyncstream(string_buffer* buf = nullptr) { // test synchronization OSyncStream oss(buf); oss << "Last "; - { OSyncStream(oss.get_wrapped()) << "First Input!\n"; } + { + OSyncStream(oss.get_wrapped()) << "First Input!\n"; + } oss << "Input!" << '\n'; } if (buf) { diff --git a/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp b/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp index 5d1c50b6056..c9bdbdd62f5 100644 --- a/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp +++ b/tests/std/tests/P0083R3_splicing_maps_and_sets/test.cpp @@ -155,8 +155,12 @@ void test_node_handle(NodeHandle& nh1, NodeHandle& nh2, Validator1 v1, Validator CHECK_EMPTY(NodeHandle{}); #ifndef _M_CEE // TRANSITION, VSO-1664382 #if _HAS_CXX20 -#pragma warning(suppress : 4640) // C4640 emitted by MSVC because 'NodeHandle' type has non-trivial dtor - { static constinit NodeHandle static_handle{}; } +#pragma warning(push) +#pragma warning(disable : 4640) // C4640 emitted by MSVC because 'NodeHandle' type has non-trivial dtor + { + static constinit NodeHandle static_handle{}; + } +#pragma warning(pop) #endif // ^^^ _HAS_CXX20 ^^^ #endif // ^^^ no workaround ^^^ @@ -387,7 +391,7 @@ void test_merge_single() { } }(1); auto const pos = std::as_const(c1).find(key); - auto c2 = extended_merge_ctype{{0, 0}, {3, 3}}; + auto c2 = extended_merge_ctype{{0, 0}, {3, 3}}; allocation_allowed = false; assert(c1.get_allocator() == c2.get_allocator()); if constexpr (Move == should_move::yes) { diff --git a/tests/std/tests/P0218R1_filesystem/test.cpp b/tests/std/tests/P0218R1_filesystem/test.cpp index ef3e44f79c2..32413cd8215 100644 --- a/tests/std/tests/P0218R1_filesystem/test.cpp +++ b/tests/std/tests/P0218R1_filesystem/test.cpp @@ -1267,7 +1267,9 @@ void test_directory_iterator_common_parts(const string_view typeName) { // DirectoryIterator() noexcept; // ~DirectoryIterator(); - { DirectoryIterator default_ctor; } + { + DirectoryIterator default_ctor; + } // explicit DirectoryIterator(const path& _Path_arg); // DirectoryIterator(const path& _Path_arg, directory_options _Options_arg); diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index a03ff3a220d..dac4ec93ae0 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -1284,20 +1284,14 @@ namespace test_lwg_3950 { template concept characterized_traits = requires { typename Traits::is_characterized; }; -#ifdef __clang__ // TRANSITION, LLVM-75404 -#define CONST_PARAM const -#else // ^^^ workaround / no workaround vvv -#define CONST_PARAM -#endif // ^^^ no workaround ^^^ - template - constexpr bool operator==(CONST_PARAM basic_string_view x, - CONST_PARAM type_identity_t> y) noexcept { + constexpr bool operator==( + basic_string_view x, type_identity_t> y) noexcept { return x.size() == y.size() && x.compare(y) == 0; } template - constexpr get_string_comparison_category_t operator<=>(CONST_PARAM basic_string_view x, - CONST_PARAM type_identity_t> y) noexcept { + constexpr get_string_comparison_category_t operator<=>( + basic_string_view x, type_identity_t> y) noexcept { return static_cast>(x.compare(y) <=> 0); } diff --git a/tests/std/tests/P0288R9_move_only_function/test.cpp b/tests/std/tests/P0288R9_move_only_function/test.cpp index cb3dd580090..e0c30ad480f 100644 --- a/tests/std/tests/P0288R9_move_only_function/test.cpp +++ b/tests/std/tests/P0288R9_move_only_function/test.cpp @@ -214,16 +214,17 @@ void test_assign() { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wself-move" #endif // __clang__ +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object { test_function_t f1{small_callable{}}; test_function_t f2{large_callable{}}; f1 = move(f1); // deliberate self-move as a test case -#pragma warning(suppress : 26800) // use a moved-from object assert(f1(23, x) == 38); f2 = move(f2); // deliberate self-move as a test case -#pragma warning(suppress : 26800) // use a moved-from object assert(f2(23, x) == 39); } +#pragma warning(pop) #ifdef __clang__ #pragma clang diagnostic pop #endif // __clang__ @@ -294,9 +295,11 @@ void test_empty() { assert(nullptr == no_callable); test_function_t no_callable_moved = move(no_callable); -#pragma warning(suppress : 26800) // use a moved-from object +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object assert(!no_callable); assert(no_callable == nullptr); +#pragma warning(pop) assert(!no_callable_moved); assert(no_callable_moved == nullptr); } @@ -339,9 +342,11 @@ void test_inner() { move_only_function f1(nullptr); move_only_function f2 = move(f1); assert(!f2); -#pragma warning(suppress : 26800) // use a moved-from object +#pragma warning(push) +#pragma warning(disable : 26800) // use a moved-from object f2 = move(f1); assert(!f1); +#pragma warning(pop) } @@ -498,8 +503,10 @@ static_assert(is_same_v::result bool fail_allocations = false; -#pragma warning(suppress : 28251) // Inconsistent annotation for 'new': this instance has no annotations. +#pragma warning(push) +#pragma warning(disable : 28251) // Inconsistent annotation for 'new': this instance has no annotations. void* operator new(size_t size) { +#pragma warning(pop) if (fail_allocations) { throw bad_alloc{}; } diff --git a/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp b/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp index e3c2f6570e5..221df456f34 100644 --- a/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp +++ b/tests/std/tests/P0414R2_shared_ptr_for_arrays/test.cpp @@ -236,11 +236,11 @@ void test_shared_ptr_all_copy_ctors() { const shared_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, const shared_ptr&>); // GOOD: same (plain, not converting) @@ -297,7 +297,7 @@ void test_shared_ptr_all_move_ctors() { !is_constructible_v, shared_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, shared_ptr>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - shared_ptr>); // BAD: unknown-to-known isn't allowed + shared_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, shared_ptr>); // GOOD: same (plain, not converting) @@ -351,10 +351,10 @@ void test_shared_ptr_weak_ctor() { const weak_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_constructible_v, const weak_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_constructible_v, const weak_ptr&>); // GOOD: same impl_shared_ptr_weak_ctor(); @@ -406,7 +406,7 @@ void test_shared_ptr_unique_ctor() { STATIC_ASSERT( !is_constructible_v, unique_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(!is_constructible_v, - unique_ptr>); // BAD: unknown-to-known isn't allowed + unique_ptr>); // BAD: unknown-to-known isn't allowed impl_shared_ptr_unique_ctor(); impl_shared_ptr_unique_ctor(); @@ -678,11 +678,11 @@ void test_weak_ptr_all_copy_ctors_and_shared_ctor() { const weak_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const weak_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const weak_ptr&>); // BAD: unknown-to-known isn't allowed + const weak_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, const weak_ptr&>); // GOOD: same (plain, not converting) @@ -708,11 +708,11 @@ void test_weak_ptr_all_copy_ctors_and_shared_ctor() { const shared_ptr&>); // GOOD: known-to-unknown is compatible STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - const shared_ptr&>); // BAD: unknown-to-known isn't allowed + const shared_ptr&>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT( is_nothrow_constructible_v, const shared_ptr&>); // GOOD: same @@ -768,7 +768,7 @@ void test_weak_ptr_all_move_ctors() { !is_constructible_v, weak_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, weak_ptr>); // GOOD: adds const STATIC_ASSERT(!is_constructible_v, - weak_ptr>); // BAD: unknown-to-known isn't allowed + weak_ptr>); // BAD: unknown-to-known isn't allowed STATIC_ASSERT(is_nothrow_constructible_v, weak_ptr>); // GOOD: same (plain, not converting) diff --git a/tests/std/tests/P0433R2_deduction_guides/test.cpp b/tests/std/tests/P0433R2_deduction_guides/test.cpp index 02de419f829..e4f7407ca47 100644 --- a/tests/std/tests/P0433R2_deduction_guides/test.cpp +++ b/tests/std/tests/P0433R2_deduction_guides/test.cpp @@ -710,8 +710,7 @@ void test_set_or_multiset() { } template