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__) && defined(__64BIT__)) +// 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 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) + mutable 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 @@ -774,7 +780,17 @@ basic_ios<_CharT, _Traits>::fill() const { if (traits_type::eq_int_type(traits_type::eof(), __fill_)) + { +#if defined(_LIBCPP_BASIC_IOS_HAS_FILL_SET) + if (!__fill_set_) + { + __fill_set_ = true; + __fill_ = widen(' '); + } +#else __fill_ = widen(' '); +#endif + } return __fill_; } @@ -783,9 +799,7 @@ _CharT basic_ios<_CharT, _Traits>::fill(char_type __ch) { - if (traits_type::eq_int_type(traits_type::eof(), __fill_)) - __fill_ = widen(' '); - char_type __r = __fill_; + char_type __r = fill(); __fill_ = __ch; return __r; } @@ -800,6 +814,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 +832,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 +845,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_wcharmax.pass.cpp b/libcxx/test/std/input.output/iostream.format/std.manip/setfill_wcharmax.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/iostream.format/std.manip/setfill_wcharmax.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// XFAIL: stdlib=libc++ && target=aarch64-linux-gnu +// XFAIL: stdlib=libc++ && target=armv7l-linux-gnueabihf +// XFAIL: stdlib=libc++ && target=armv8l-linux-gnueabihf +// XFAIL: stdlib=libc++ && target=x86_64-pc-windows-msvc +// XFAIL: stdlib=libc++ && target=x86_64-w64-windows-gnu + +// + +// template T4 setfill(charT c); + +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct testbuf + : public std::basic_streambuf +{ + testbuf() {} +}; + +int main(int, char**) +{ +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + testbuf sb; + std::wostream os(&sb); + os << std::setfill(std::numeric_limits::max()); + assert(os.fill() == std::numeric_limits::max()); + } +#endif + + return 0; +}