From 5cae4fb223f41fe1aafb2befbba2ad218a706688 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 19 Mar 2026 13:36:52 -0700 Subject: [PATCH 1/3] Avoid calling frexp() for inf/nan. --- stl/inc/xlocnum | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 29c3b8540ba..265161cd9f4 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1385,15 +1385,15 @@ protected: const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting const int _Desired_precision = _Float_put_desired_precision(_Precision, _Float_flags); // desired precision - size_t _Bufsize = static_cast(_Desired_precision); - if (_Is_fixed && 1e10 < _CSTD fabs(_Val)) { // f or F format + size_t _Bufsize = static_cast(_Desired_precision); + const bool _Is_finite = (_STD isfinite) (_Val); + if (_Is_fixed && _Is_finite && 1e10 < _CSTD fabs(_Val)) { // f or F format int _Ptwo; (void) _CSTD frexp(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; } _Buf.resize(_Bufsize + 50); // add fudge factor - const bool _Is_finite = (_STD isfinite) (_Val); const auto _Adjusted_flags = // TRANSITION, DevCom-10519861 _Is_finite ? _Iosbase.flags() : _Iosbase.flags() & ~ios_base::showpoint; @@ -1419,15 +1419,15 @@ protected: const streamsize _Precision = _Is_hex ? -1 : _Iosbase.precision(); // precision setting const int _Desired_precision = _Float_put_desired_precision(_Precision, _Float_flags); // desired precision - size_t _Bufsize = static_cast(_Desired_precision); - if (_Is_fixed && 1e10 < _CSTD fabsl(_Val)) { // f or F format + size_t _Bufsize = static_cast(_Desired_precision); + const bool _Is_finite = (_STD isfinite) (_Val); + if (_Is_fixed && _Is_finite && 1e10 < _CSTD fabsl(_Val)) { // f or F format int _Ptwo; (void) _CSTD frexpl(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; } _Buf.resize(_Bufsize + 50); // add fudge factor - const bool _Is_finite = (_STD isfinite) (_Val); const auto _Adjusted_flags = // TRANSITION, DevCom-10519861 _Is_finite ? _Iosbase.flags() : _Iosbase.flags() & ~ios_base::showpoint; From c44af801a91c1d85bc28cada8fab1b1f92a3d1c0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 19 Mar 2026 13:37:53 -0700 Subject: [PATCH 2/3] Avoid garbage-init for frexp()'s integer exponent. --- stl/inc/random | 2 +- stl/inc/xlocnum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/random b/stl/inc/random index 1b558903ea9..eb3496e162a 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -70,7 +70,7 @@ _INLINE_VAR constexpr int _Nwords = 4; template basic_ostream<_Elem, _Traits>& _Write( basic_ostream<_Elem, _Traits>& _Os, long double _Dx) { // write long double to stream - int _Ex; + int _Ex = 0; long double _Frac = _CSTD frexpl(_Dx, &_Ex); for (int _Nw = 0; _Nw < _Nwords; ++_Nw) { // break into 31-bit words _Frac *= _Two31; diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 265161cd9f4..858ce353923 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1388,7 +1388,7 @@ protected: size_t _Bufsize = static_cast(_Desired_precision); const bool _Is_finite = (_STD isfinite) (_Val); if (_Is_fixed && _Is_finite && 1e10 < _CSTD fabs(_Val)) { // f or F format - int _Ptwo; + int _Ptwo = 0; (void) _CSTD frexp(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; } @@ -1422,7 +1422,7 @@ protected: size_t _Bufsize = static_cast(_Desired_precision); const bool _Is_finite = (_STD isfinite) (_Val); if (_Is_fixed && _Is_finite && 1e10 < _CSTD fabsl(_Val)) { // f or F format - int _Ptwo; + int _Ptwo = 0; (void) _CSTD frexpl(_Val, &_Ptwo); _Bufsize += _CSTD abs(_Ptwo) * 30103L / 100000L; } From c814ee3f5ac3bdef78aae02b6ab51b131502968e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 19 Mar 2026 13:52:22 -0700 Subject: [PATCH 3/3] Enhance test coverage to expect specific strings. --- tests/std/tests/GH_003867_output_nan/test.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/std/tests/GH_003867_output_nan/test.cpp b/tests/std/tests/GH_003867_output_nan/test.cpp index 059ed13cca5..b25ed7cf176 100644 --- a/tests/std/tests/GH_003867_output_nan/test.cpp +++ b/tests/std/tests/GH_003867_output_nan/test.cpp @@ -58,7 +58,8 @@ void test_gh_3867() { // Also test GH-4210: With setprecision(0) showpoint fixed, a bogus '.' is emitted for infinity and NaN template -void test_output_nonfinite_value(const FloatingPoint x) { +void test_output_nonfinite_value( + const FloatingPoint x, const string& expected_noshowpos, const string& expected_showpos) { const auto s1 = [x] { ostringstream os; os << setprecision(0) << showpoint << fixed; @@ -72,6 +73,7 @@ void test_output_nonfinite_value(const FloatingPoint x) { return os.str(); }(); assert(s1 == s2); + assert(s1 == expected_noshowpos); const auto s3 = [x] { ostringstream os; @@ -86,6 +88,7 @@ void test_output_nonfinite_value(const FloatingPoint x) { return os.str(); }(); assert(s3 == s4); + assert(s3 == expected_showpos); } template @@ -93,10 +96,11 @@ void test_gh_4210() { constexpr auto inf_val = numeric_limits::infinity(); constexpr auto nan_val = numeric_limits::quiet_NaN(); - test_output_nonfinite_value(inf_val); - test_output_nonfinite_value(-inf_val); - test_output_nonfinite_value(nan_val); - test_output_nonfinite_value(-nan_val); + // These expected results are implementation-defined: + test_output_nonfinite_value(inf_val, "inf", "+inf"); + test_output_nonfinite_value(-inf_val, "-inf", "-inf"); + test_output_nonfinite_value(nan_val, "nan", "+nan"); + test_output_nonfinite_value(-nan_val, "-nan(ind)", "-nan(ind)"); } int main() {