From 2357ce4ceedc573b1d606547a772cf4ff677cd05 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 20 Nov 2023 01:06:19 +0800 Subject: [PATCH 1/3] Drop `ios_base::showpoint` when printing non-finite values --- stl/inc/xlocnum | 14 ++++-- tests/std/tests/GH_003867_output_nan/test.cpp | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index afe27df46d..a35bae9acd 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1371,10 +1371,13 @@ protected: } _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; const auto _Ngen = static_cast(_CSTD sprintf_s( - &_Buf[0], _Buf.size(), _Ffmt(_Fmt, 0, _Iosbase.flags()), static_cast(_Precision), _Val)); + &_Buf[0], _Buf.size(), _Ffmt(_Fmt, 0, _Adjusted_flags), static_cast(_Precision), _Val)); - return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, (_STD isfinite)(_Val)); + return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, _Is_finite); } virtual _OutIt __CLR_OR_THIS_CALL do_put( @@ -1395,10 +1398,13 @@ protected: } _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; const auto _Ngen = static_cast(_CSTD sprintf_s( - &_Buf[0], _Buf.size(), _Ffmt(_Fmt, 'L', _Iosbase.flags()), static_cast(_Precision), _Val)); + &_Buf[0], _Buf.size(), _Ffmt(_Fmt, 'L', _Adjusted_flags), static_cast(_Precision), _Val)); - return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, (_STD isfinite)(_Val)); + return _Fput_v3(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, _Is_finite); } #pragma warning(pop) diff --git a/tests/std/tests/GH_003867_output_nan/test.cpp b/tests/std/tests/GH_003867_output_nan/test.cpp index e36c6779fc..ee13031908 100644 --- a/tests/std/tests/GH_003867_output_nan/test.cpp +++ b/tests/std/tests/GH_003867_output_nan/test.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include #include #include @@ -54,8 +55,56 @@ void test_gh_3867() { #endif // TEST_CUSTOM_FACET } +// Also test GH-4210: With setprecision(0) showpoint fixed, a bogus '.' is emitted for infinity and NaN + +template +void test_output_nonfinite_value(FloatingPoint x) { + auto s1 = [x] { + ostringstream os; + os << setprecision(0) << showpoint << fixed; + os << x; + return os.str(); + }(); + auto s2 = [x] { + ostringstream os; + os << setprecision(0) << noshowpoint << fixed; + os << x; + return os.str(); + }(); + assert(s1 == s2); + + auto s3 = [x] { + ostringstream os; + os << setprecision(0) << showpoint << fixed << showpos; + os << x; + return os.str(); + }(); + auto s4 = [x] { + ostringstream os; + os << setprecision(0) << noshowpoint << fixed << showpos; + os << x; + return os.str(); + }(); + assert(s3 == s3); +} + +template +void test_gh_4210() { + constexpr auto inf_dbl = numeric_limits::infinity(); + constexpr auto nan_dbl = numeric_limits::quiet_NaN(); + + test_output_nonfinite_value(inf_dbl); + test_output_nonfinite_value(-inf_dbl); + test_output_nonfinite_value(nan_dbl); + test_output_nonfinite_value(-nan_dbl); +} + int main() { test_gh_3867(); test_gh_3867(); test_gh_3867(); + + test_gh_4210(); + test_gh_4210(); + test_gh_4210(); } From ed23720e8b62fc9af6e5df35b224eac4e1b147db Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 20 Nov 2023 11:35:28 +0800 Subject: [PATCH 2/3] Drop one strange space --- stl/inc/xlocnum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index a35bae9acd..cb0ddec757 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1399,7 +1399,7 @@ protected: _Buf.resize(_Bufsize + 50); // add fudge factor const bool _Is_finite = (_STD isfinite)(_Val); - const auto _Adjusted_flags = // TRANSITION, DevCom-10519861 + const auto _Adjusted_flags = // TRANSITION, DevCom-10519861 _Is_finite ? _Iosbase.flags() : _Iosbase.flags() & ~ios_base::showpoint; const auto _Ngen = static_cast(_CSTD sprintf_s( &_Buf[0], _Buf.size(), _Ffmt(_Fmt, 'L', _Adjusted_flags), static_cast(_Precision), _Val)); From aca6a973419cd992cdcb50ce74478ac3e070cae3 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 28 Nov 2023 14:59:22 -0800 Subject: [PATCH 3/3] Fix test coverage and other CR feedback. --- tests/std/tests/GH_003867_output_nan/test.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/std/tests/GH_003867_output_nan/test.cpp b/tests/std/tests/GH_003867_output_nan/test.cpp index ee13031908..059ed13cca 100644 --- a/tests/std/tests/GH_003867_output_nan/test.cpp +++ b/tests/std/tests/GH_003867_output_nan/test.cpp @@ -58,14 +58,14 @@ 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(FloatingPoint x) { - auto s1 = [x] { +void test_output_nonfinite_value(const FloatingPoint x) { + const auto s1 = [x] { ostringstream os; os << setprecision(0) << showpoint << fixed; os << x; return os.str(); }(); - auto s2 = [x] { + const auto s2 = [x] { ostringstream os; os << setprecision(0) << noshowpoint << fixed; os << x; @@ -73,30 +73,30 @@ void test_output_nonfinite_value(FloatingPoint x) { }(); assert(s1 == s2); - auto s3 = [x] { + const auto s3 = [x] { ostringstream os; os << setprecision(0) << showpoint << fixed << showpos; os << x; return os.str(); }(); - auto s4 = [x] { + const auto s4 = [x] { ostringstream os; os << setprecision(0) << noshowpoint << fixed << showpos; os << x; return os.str(); }(); - assert(s3 == s3); + assert(s3 == s4); } template void test_gh_4210() { - constexpr auto inf_dbl = numeric_limits::infinity(); - constexpr auto nan_dbl = numeric_limits::quiet_NaN(); + constexpr auto inf_val = numeric_limits::infinity(); + constexpr auto nan_val = numeric_limits::quiet_NaN(); - test_output_nonfinite_value(inf_dbl); - test_output_nonfinite_value(-inf_dbl); - test_output_nonfinite_value(nan_dbl); - test_output_nonfinite_value(-nan_dbl); + test_output_nonfinite_value(inf_val); + test_output_nonfinite_value(-inf_val); + test_output_nonfinite_value(nan_val); + test_output_nonfinite_value(-nan_val); } int main() {