diff --git a/stl/inc/xloctime b/stl/inc/xloctime index 06652fd4c..89e4e1ca7 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -735,7 +735,8 @@ protected: _Fmt[3] = _Specifier; } - const int& _Errno_ref = errno; // Nonzero cost, pay it once + int& _Errno_ref = errno; // Nonzero cost, pay it once + const int _Old_errno = _Errno_ref; for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); @@ -748,6 +749,7 @@ protected: } } + _Errno_ref = _Old_errno; return _STD copy(&_Str[1], &_Str[_Count], _Dest); } @@ -864,7 +866,8 @@ protected: _Fmt[3] = static_cast<_Elem>(_Specifier); } - const int& _Errno_ref = errno; // Nonzero cost, pay it once + int& _Errno_ref = errno; // Nonzero cost, pay it once + const int _Old_errno = _Errno_ref; for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); @@ -876,6 +879,8 @@ protected: return _Dest; } } + + _Errno_ref = _Old_errno; return _STD copy(&_Str[1], &_Str[_Count], _Dest); } @@ -993,7 +998,8 @@ protected: _Fmt[3] = static_cast<_Elem>(_Specifier); } - const int& _Errno_ref = errno; // Nonzero cost, pay it once + int& _Errno_ref = errno; // Nonzero cost, pay it once + const int _Old_errno = _Errno_ref; for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); @@ -1006,6 +1012,7 @@ protected: } } + _Errno_ref = _Old_errno; return _STD copy(&_Str[1], &_Str[_Count], _Dest); } diff --git a/tests/std/test.lst b/tests/std/test.lst index 80bd87fb6..5121260b7 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -193,6 +193,7 @@ tests\GH_001964_constexpr_generate_canonical tests\GH_002030_asan_annotate_string tests\GH_002030_asan_annotate_vector tests\GH_002039_byte_is_not_trivially_swappable +tests\GH_002045_put_time_changes_errno tests\GH_002058_debug_iterator_race tests\GH_002120_streambuf_seekpos_and_seekoff tests\GH_002299_implicit_sfinae_constraints diff --git a/tests/std/tests/GH_002045_put_time_changes_errno/env.lst b/tests/std/tests/GH_002045_put_time_changes_errno/env.lst new file mode 100644 index 000000000..19f025bd0 --- /dev/null +++ b/tests/std/tests/GH_002045_put_time_changes_errno/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_002045_put_time_changes_errno/test.cpp b/tests/std/tests/GH_002045_put_time_changes_errno/test.cpp new file mode 100644 index 000000000..fe2cc6040 --- /dev/null +++ b/tests/std/tests/GH_002045_put_time_changes_errno/test.cpp @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace chrono; + +tm tm_now() { + const time_t t(system_clock::to_time_t(system_clock::now())); + + tm tm_val; + + const errno_t err = localtime_s(&tm_val, &t); + assert(err == 0); + + return tm_val; +} + +int main() { + const tm tm_val = tm_now(); + + { + ostringstream os; + + assert(errno == 0); + + os << put_time(&tm_val, "%Y-%m-%d %H:%M:%S %Z"); + + assert(os); + assert(errno == 0); + } + { + wostringstream os; + + assert(errno == 0); + + os << put_time(&tm_val, L"%Y-%m-%d %H:%M:%S %Z"); + + assert(os); + assert(errno == 0); + } +}