The _Padding_sink was behaving incorreclty, when the predicated width (based on code units counts) was higher than _M_maxwidth, but lower than _M_padwidth. In this case _M_update() returned without calling _M_force_update() and computing field width for Unicode encondings, because _M_buffering() returns 'true'. As cosnequence we switched to _M_ignoring() mode with prefix of smaller lenght.
We now call _M_force_update() if predicted witdh is greater than either _M_padwidth or _M_maxwidth. This was detected for existing test case on 32bit achicture. libstdc++-v3/ChangeLog: * include/std/format (_Padding_sink::_M_update): Fixed condition for calling _M_force_update. * testsuite/std/format/debug.cc: Add test that reproducers this issue on 64bit architevture. --- Tested only debug.cc now for x64_64-linux with and without -m32. With peform full test on Monday, but sending patch to inform about issue. This is GCC 16 only. libstdc++-v3/include/std/format | 6 +++--- libstdc++-v3/testsuite/std/format/debug.cc | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 69d8d189db6..a9e4beca9ca 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -3697,9 +3697,9 @@ namespace __format _M_update(size_t __new) { _M_printwidth += __new; - if (_M_buffering()) - return true; - return _M_force_update(); + if (_M_printwidth > _M_padwidth || _M_printwidth > _M_maxwidth) + return _M_force_update(); + return true; } void diff --git a/libstdc++-v3/testsuite/std/format/debug.cc b/libstdc++-v3/testsuite/std/format/debug.cc index d3402f80f4b..6165a295496 100644 --- a/libstdc++-v3/testsuite/std/format/debug.cc +++ b/libstdc++-v3/testsuite/std/format/debug.cc @@ -596,6 +596,10 @@ void test_padding() VERIFY( strip_prefix(resv, 48, '*') ); VERIFY( resv == inv ); + resv = res = std::format("{:*>300.200s}", in); + VERIFY( strip_prefix(resv, 108, '*') ); + VERIFY( resv == inv ); + resv = res = std::format("{:*>240.200s}", in); VERIFY( strip_prefix(resv, 48, '*') ); VERIFY( resv == inv ); @@ -678,6 +682,11 @@ void test_padding() VERIFY( strip_quotes(resv) ); VERIFY( resv == inv ); + resv = res = std::format("{:*>300.200?}", in); + VERIFY( strip_prefix(resv, 106, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + resv = res = std::format("{:*>240.200?}", in); VERIFY( strip_prefix(resv, 46, '*') ); VERIFY( strip_quotes(resv) ); -- 2.49.0