Skip to content

Commit

Permalink
fix writing NaN to the output stream with a set locale (#3868)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
  • Loading branch information
fsb4000 and StephanTLavavej authored Jul 14, 2023
1 parent 0574f20 commit 28ea30a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
28 changes: 18 additions & 10 deletions stl/inc/xlocnum
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ protected:
const auto _Ngen = static_cast<size_t>(_CSTD sprintf_s(
&_Buf[0], _Buf.size(), _Ffmt(_Fmt, 0, _Iosbase.flags()), static_cast<int>(_Precision), _Val));

return _Fput(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen);
return _Fput_v2(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, (_STD isnan)(_Val));
}

virtual _OutIt __CLR_OR_THIS_CALL do_put(
Expand All @@ -1400,7 +1400,7 @@ protected:
const auto _Ngen = static_cast<size_t>(_CSTD sprintf_s(
&_Buf[0], _Buf.size(), _Ffmt(_Fmt, 'L', _Iosbase.flags()), static_cast<int>(_Precision), _Val));

return _Fput(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen);
return _Fput_v2(_Dest, _Iosbase, _Fill, _Buf.c_str(), _Ngen, (_STD isnan)(_Val));
}
#pragma warning(pop)

Expand Down Expand Up @@ -1462,7 +1462,13 @@ private:
}

_OutIt __CLRCALL_OR_CDECL _Fput(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const char* _Buf,
size_t _Count) const { // put formatted floating-point to _Dest
size_t _Count) const { // TRANSITION, ABI: preserved for binary compatibility
return _Fput_v2(_Dest, _Iosbase, _Fill, _Buf, _Count, false);
}

template <int = 0> // TRANSITION, ABI
_OutIt _Fput_v2(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const char* _Buf, size_t _Count,
bool _Is_nan_val) const { // put formatted floating-point to _Dest
auto _Prefix = static_cast<size_t>(0 < _Count && (*_Buf == '+' || *_Buf == '-'));
const char* _Exps;
if ((_Iosbase.flags() & ios_base::floatfield) != ios_base::hexfloat) {
Expand Down Expand Up @@ -1491,13 +1497,15 @@ private:
_Groupstring[_Poff] = _Punct_fac.decimal_point();
}

size_t _Off = _Poff == _Count ? _Eoff : _Poff;
const char* _Pg = &_Grouping[0];
while (*_Pg != CHAR_MAX && '\0' < *_Pg && static_cast<size_t>(*_Pg) < _Off - _Prefix) {
// add thousands separator
_Groupstring.insert(_Off -= *_Pg, 1, _Kseparator);
if ('\0' < _Pg[1]) {
++_Pg; // not last group, advance
if (!_Is_nan_val) {
size_t _Off = _Poff == _Count ? _Eoff : _Poff;
const char* _Pg = &_Grouping[0];
while (*_Pg != CHAR_MAX && '\0' < *_Pg && static_cast<size_t>(*_Pg) < _Off - _Prefix) {
// add thousands separator
_Groupstring.insert(_Off -= *_Pg, 1, _Kseparator);
if ('\0' < _Pg[1]) {
++_Pg; // not last group, advance
}
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ tests\GH_003617_vectorized_meow_element
tests\GH_003676_format_large_hh_mm_ss_values
tests\GH_003735_char_traits_signatures
tests\GH_003840_tellg_when_reading_lf_file_in_text_mode
tests\GH_003867_output_nan
tests\LWG2381_num_get_floating_point
tests\LWG2597_complex_branch_cut
tests\LWG3018_shared_ptr_function
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/GH_003867_output_nan/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_matrix.lst
24 changes: 24 additions & 0 deletions tests/std/tests/GH_003867_output_nan/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <limits>
#include <locale>
#include <sstream>

using namespace std;

template <typename T>
void test_gh_3867() {
// GH-3867 Writing NaN to the output stream with a set locale results in a weird output
ostringstream s;
s.imbue(locale("en-US"));
s << -numeric_limits<T>::quiet_NaN();
assert(s.str() == "-nan(ind)");
}

int main() {
test_gh_3867<float>();
test_gh_3867<double>();
test_gh_3867<long double>();
}

0 comments on commit 28ea30a

Please sign in to comment.