diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -312,6 +312,14 @@ # define _LIBCPP_SHORT_WCHAR 1 #endif +#if defined(_AIX) || defined(__MVS__) +// On AIX and zOS in 64-bit, wint_t is not able to represent any wchar_t value as well as WEOF +// because wint_t and wchar_t have the same size, consequently an additional member is +// needed to indicate if the fill value is initialized. +// Enabled in 32-bit for compatibility with the IBM AIX/zOS provided libc++. +# define _LIBCPP_BASIC_IOS_HAS_FILL_SET 1 +#endif + // Libc++ supports various implementations of std::random_device. // // _LIBCPP_USING_DEV_RANDOM diff --git a/libcxx/include/ios b/libcxx/include/ios --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -680,6 +680,9 @@ private: basic_ostream* __tie_; mutable int_type __fill_; +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + bool __fill_set_; +#endif }; template @@ -702,6 +705,9 @@ ios_base::init(__sb); __tie_ = nullptr; __fill_ = traits_type::eof(); +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + __fill_set_ = false; +#endif } template @@ -773,7 +779,11 @@ _CharT basic_ios<_CharT, _Traits>::fill() const { +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + if (!__fill_set_) +#else if (traits_type::eq_int_type(traits_type::eof(), __fill_)) +#endif __fill_ = widen(' '); return __fill_; } @@ -783,10 +793,17 @@ _CharT basic_ios<_CharT, _Traits>::fill(char_type __ch) { +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + if (!__fill_set_) +#else if (traits_type::eq_int_type(traits_type::eof(), __fill_)) +#endif __fill_ = widen(' '); char_type __r = __fill_; __fill_ = __ch; +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + __fill_set_ = true; +#endif return __r; } @@ -800,6 +817,9 @@ ios_base::copyfmt(__rhs); __tie_ = __rhs.__tie_; __fill_ = __rhs.__fill_; +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + __fill_set_ = __rhs.__fill_set_; +#endif __call_callbacks(copyfmt_event); exceptions(__rhs.exceptions()); } @@ -815,6 +835,9 @@ __tie_ = __rhs.__tie_; __rhs.__tie_ = nullptr; __fill_ = __rhs.__fill_; +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + __fill_set_ = __rhs.__fill_set_; +#endif } template @@ -825,6 +848,9 @@ ios_base::swap(__rhs); _VSTD::swap(__tie_, __rhs.__tie_); _VSTD::swap(__fill_, __rhs.__fill_); +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + _VSTD::swap(__fill_set_, __rhs.__fill_set_); +#endif } template diff --git a/libcxx/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp b/libcxx/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "test_macros.h" @@ -38,6 +39,13 @@ os << std::setfill(L'*'); assert(os.fill() == L'*'); } + + { + testbuf sb; + std::wostream os(&sb); + os << std::setfill(std::numeric_limits::max()); + assert(os.fill() == std::numeric_limits::max()); + } #endif return 0;