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

Reply via email to