From 21c1255a9306cefd3b61360331e08e269490ffc5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 31 Aug 2026 11:45:16 -0700 Subject: [PATCH 1/3] cmath: Use builtins for MSVC /Zc:cmath in all Standard modes, not just C++23. --- stl/inc/cmath | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/cmath b/stl/inc/cmath index 0d16a11250..d6d3c6724a 100644 --- a/stl/inc/cmath +++ b/stl/inc/cmath @@ -11,14 +11,14 @@ #include #include -// MSVC provides constexpr builtins in C++23 and later, except when /Zc:cmath- opts out of constexpr. -#if defined(__clang__) || defined(__cpp_lib_constexpr_cmath) +// Clang and MSVC /Zc:cmath provide builtins. +#if defined(__clang__) || defined(_MSVC_LIBC_MATH) #define _HAS_CMATH_BUILTINS 1 #else // ^^^ builtins available / builtins unavailable vvv #define _HAS_CMATH_BUILTINS 0 #endif // ^^^ builtins unavailable ^^^ -// When constexpr builtins are unavailable, fall back to intrinsics for better codegen. +// When builtins are unavailable, fall back to intrinsics for better codegen. #if !_HAS_CMATH_BUILTINS && !defined(_M_CEE) // TRANSITION, VSO-1663104 #define _HAS_CMATH_INTRINSICS 1 #else // ^^^ intrinsics available / intrinsics unavailable vvv From 99ceb8886598cfbcc8ef687a45452f8f0b10cf84 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 31 Aug 2026 11:48:43 -0700 Subject: [PATCH 2/3] P0533R9_constexpr_for_cmath_and_cstdlib/test.cpp: Update to work in all Standard modes. --- .../test.cpp | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/test.cpp b/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/test.cpp index 18030a5df9..bab2db5263 100644 --- a/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/test.cpp +++ b/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/test.cpp @@ -8,13 +8,32 @@ #include using namespace std; +#if !_HAS_CXX17 +#pragma warning(disable : 4984) // 'if constexpr' is a C++17 language extension +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wc++17-extensions" // warning: constexpr if is a C++17 extension +#endif // ^^^ defined(__clang__) ^^^ +#endif // ^^^ !_HAS_CXX17 ^^^ + +#ifdef __cpp_lib_constexpr_cmath +#define CONSTEXPR_CMATH23 constexpr +#else +#define CONSTEXPR_CMATH23 inline +#endif + +#if _HAS_CXX26 && defined(_MSVC_LIBC_MATH) // TRANSITION, GH-3789, should be `__cpp_lib_constexpr_cmath >= 202306L` +#define CONSTEXPR_CMATH26 constexpr +#else +#define CONSTEXPR_CMATH26 inline +#endif + template -constexpr void test_classification_functions_cxx23(); +CONSTEXPR_CMATH23 void test_classification_functions_cxx23(); template -constexpr void test_comparison_functions_cxx23(); +CONSTEXPR_CMATH23 void test_comparison_functions_cxx23(); -constexpr bool test_cmath_cxx23() { +CONSTEXPR_CMATH23 bool test_cmath_cxx23() { #if defined(_MSVC_INTERNAL_TESTING) || !defined(_MSVC_LIBC_MATH) // TRANSITION, MSVC-PR-767184/772024 fixed LNK2005 { int exponent = 0; @@ -220,7 +239,7 @@ constexpr bool test_cmath_cxx23() { test_classification_functions_cxx23(); #ifndef _MSVC_INTERNAL_TESTING // TRANSITION, MSVC-PR-767404 fixed the comparison functions in constant evaluation - if !consteval + if (!_Is_constant_evaluated()) #endif // ^^^ workaround ^^^ { test_comparison_functions_cxx23(); @@ -233,7 +252,7 @@ constexpr bool test_cmath_cxx23() { } template -constexpr void test_classification_functions_cxx23() { +CONSTEXPR_CMATH23 void test_classification_functions_cxx23() { { constexpr T zro{}; constexpr T val = static_cast(5); @@ -292,7 +311,7 @@ constexpr void test_classification_functions_cxx23() { } template -constexpr void test_comparison_functions_cxx23() { +CONSTEXPR_CMATH23 void test_comparison_functions_cxx23() { constexpr T lo = static_cast(-3); constexpr T hi = static_cast(4); @@ -352,7 +371,7 @@ constexpr void test_comparison_functions_cxx23() { } } -constexpr bool test_cstdlib_cxx23() { +CONSTEXPR_CMATH23 bool test_cstdlib_cxx23() { assert(abs(-5) == 5); assert(abs(-5L) == 5L); assert(abs(-5LL) == 5LL); @@ -380,7 +399,7 @@ constexpr bool test_cstdlib_cxx23() { return true; } -constexpr bool test_cmath_cxx26() { +CONSTEXPR_CMATH26 bool test_cmath_cxx26() { // These tests use round() because they're checking for basic functionality, not precision. assert(round(acos(0.6f) * 1000.0f) == 927.0f); @@ -432,7 +451,7 @@ constexpr bool test_cmath_cxx26() { assert(round(tanl(0.6l) * 1000.0l) == 684.0l); assert(round(tan(1729) * 1000.0) == 2087.0); - if !consteval { // TRANSITION, GH-3789 + if (!_Is_constant_evaluated()) { // TRANSITION, GH-3789 assert(round(acosh(3.3f) * 1000.0f) == 1863.0f); assert(round(acosh(3.3) * 1000.0) == 1863.0); assert(round(acosh(3.3l) * 1000.0l) == 1863.0l); @@ -483,7 +502,7 @@ constexpr bool test_cmath_cxx26() { assert(round(expl(0.6l) * 1000.0l) == 1822.0l); assert(round(exp(2) * 1000.0) == 7389.0); - if !consteval { // TRANSITION, GH-3789 + if (!_Is_constant_evaluated()) { // TRANSITION, GH-3789 assert(round(exp2(0.6f) * 1000.0f) == 1516.0f); assert(round(exp2(0.6) * 1000.0) == 1516.0); assert(round(exp2(0.6l) * 1000.0l) == 1516.0l); @@ -541,13 +560,15 @@ constexpr bool test_cmath_cxx26() { assert(round(hypotl(3.3l, 7.7l) * 1000.0l) == 8377.0l); assert(round(hypot(3, 7) * 1000.0) == 7616.0); - if !consteval { // TRANSITION, GH-3789 +#if _HAS_CXX17 + if (!_Is_constant_evaluated()) { // TRANSITION, GH-3789 assert(round(hypot(2.2f, 3.3f, 4.4f) * 1000.0f) == 5924.0f); assert(round(hypot(2.2, 3.3, 4.4) * 1000.0) == 5924.0); assert(round(hypot(2.2l, 3.3l, 4.4l) * 1000.0l) == 5924.0l); assert(round(hypot(2, 3, 4) * 1000.0) == 5385.0); // No 3-arg overloads for hypotf() and hypotl() } +#endif // ^^^ _HAS_CXX17 ^^^ assert(round(pow(3.3f, 0.6f) * 1000.0f) == 2047.0f); assert(round(pow(3.3, 0.6) * 1000.0) == 2047.0); @@ -563,7 +584,7 @@ constexpr bool test_cmath_cxx26() { assert(round(sqrtl(0.6l) * 1000.0l) == 775.0l); assert(round(sqrt(7) * 1000.0) == 2646.0); - if !consteval { // TRANSITION, GH-3789 + if (!_Is_constant_evaluated()) { // TRANSITION, GH-3789 assert(round(erf(0.6f) * 1000.0f) == 604.0f); assert(round(erf(0.6) * 1000.0) == 604.0); assert(round(erf(0.6l) * 1000.0l) == 604.0l); From 8a5a9186458b8b56bc1e62ec279f0f0b12a30d1d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 31 Aug 2026 12:11:31 -0700 Subject: [PATCH 3/3] P0533R9_constexpr_for_cmath_and_cstdlib/env.lst: Expand test matrix downlevel. --- .../env.lst | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/env.lst b/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/env.lst index 70705eeacf..f21cfd9191 100644 --- a/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/env.lst +++ b/tests/std/tests/P0533R9_constexpr_for_cmath_and_cstdlib/env.lst @@ -1,23 +1,71 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -RUNALL_INCLUDE ..\usual_latest_matrix.lst +RUNALL_INCLUDE ..\usual_matrix.lst # Explicitly enable libc-based math: # TRANSITION, MSVC-PR-766982 renamed /experimental:mathlib to /Zc:cmath, pass both until this change ships -PM_CL="/MD /Zc:cmath /experimental:mathlib" -PM_CL="/MDd /Zc:cmath /experimental:mathlib" -PM_CL="/MT /Zc:cmath /experimental:mathlib" -PM_CL="/MTd /Zc:cmath /experimental:mathlib" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++14 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++14 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++14 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++14 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++17 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++17 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++17 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++17 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++20 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++20 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++20 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++20 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++23preview /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++23preview /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++23preview /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++23preview /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++latest /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++latest /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++latest /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /std:c++latest /MTd" # /O2 implies /Oi which affects <__msvc_math.hpp>: -PM_CL="/MD /Zc:cmath /experimental:mathlib /O2" -PM_CL="/MDd /Zc:cmath /experimental:mathlib /O2" -PM_CL="/MT /Zc:cmath /experimental:mathlib /O2" -PM_CL="/MTd /Zc:cmath /experimental:mathlib /O2" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++14 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++14 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++14 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++14 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++17 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++17 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++17 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++17 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++20 /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++20 /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++20 /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++20 /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++23preview /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++23preview /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++23preview /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++23preview /MTd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++latest /MD" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++latest /MDd" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++latest /MT" +PM_CL="/EHsc /Zc:cmath /experimental:mathlib /O2 /std:c++latest /MTd" # Explicitly disable libc-based math: -PM_CL="/MD /Zc:cmath-" -PM_CL="/MDd /Zc:cmath-" -PM_CL="/MT /Zc:cmath-" -PM_CL="/MTd /Zc:cmath-" +PM_CL="/EHsc /Zc:cmath- /std:c++14 /MD" +PM_CL="/EHsc /Zc:cmath- /std:c++14 /MDd" +PM_CL="/EHsc /Zc:cmath- /std:c++14 /MT" +PM_CL="/EHsc /Zc:cmath- /std:c++14 /MTd" +PM_CL="/EHsc /Zc:cmath- /std:c++17 /MD" +PM_CL="/EHsc /Zc:cmath- /std:c++17 /MDd" +PM_CL="/EHsc /Zc:cmath- /std:c++17 /MT" +PM_CL="/EHsc /Zc:cmath- /std:c++17 /MTd" +PM_CL="/EHsc /Zc:cmath- /std:c++20 /MD" +PM_CL="/EHsc /Zc:cmath- /std:c++20 /MDd" +PM_CL="/EHsc /Zc:cmath- /std:c++20 /MT" +PM_CL="/EHsc /Zc:cmath- /std:c++20 /MTd" +PM_CL="/EHsc /Zc:cmath- /std:c++23preview /MD" +PM_CL="/EHsc /Zc:cmath- /std:c++23preview /MDd" +PM_CL="/EHsc /Zc:cmath- /std:c++23preview /MT" +PM_CL="/EHsc /Zc:cmath- /std:c++23preview /MTd" +PM_CL="/EHsc /Zc:cmath- /std:c++latest /MD" +PM_CL="/EHsc /Zc:cmath- /std:c++latest /MDd" +PM_CL="/EHsc /Zc:cmath- /std:c++latest /MT" +PM_CL="/EHsc /Zc:cmath- /std:c++latest /MTd"