On Mon, Feb 9, 2026 at 2:56 PM LIU Hao <[email protected]> wrote: > > The MSVCRT `strtoul()` function resets `errno` to zero upon success. On such > a system, `libiberty_vprintf_buffer_size()` can clobber `errno` like this: > > MINGW64 ~ > $ ld nonexistent.file > C:\MSYS64\mingw64\bin\ld.exe: cannot find nonexistent.file: No error
LGTM, please leave others some time to comment. Thanks, Richard. > libiberty/ChangeLog: > > * vprintf-support.c (do_strtoul): New function. > (libiberty_vprintf_buffer_size): Replace `strtoul` with `do_strtoul`. > > Signed-off-by: LIU Hao <[email protected]> > --- > libiberty/vprintf-support.c | 20 ++++++++++++++++++-- > 1 file changed, 18 insertions(+), 2 deletions(-) > > diff --git a/libiberty/vprintf-support.c b/libiberty/vprintf-support.c > index 5a998fbf4ae0..905e86b0437c 100644 > --- a/libiberty/vprintf-support.c > +++ b/libiberty/vprintf-support.c > @@ -27,6 +27,7 @@ Floor, Boston, MA 02110-1301, USA. */ > # define va_copy(d,s) __va_copy((d),(s)) > #endif > #include <stdio.h> > +#include <errno.h> > #ifdef HAVE_STRING_H > #include <string.h> > #endif > @@ -37,6 +38,21 @@ extern unsigned long strtoul (); > #endif > #include "libiberty.h" > +static inline unsigned long > +do_strtoul (const char *str, char **endptr, int base) > + { > +#ifdef _WIN32 > + /* The MSVCRT `strtoul()` function resets `errno` to zero upon success. > + We must preserve it across this call. */ > + int saved_errno = errno; > +#endif > + long value = strtoul (str, endptr, base); > +#ifdef _WIN32 > + errno = saved_errno; > +#endif > + return value; > + } > + > int > libiberty_vprintf_buffer_size (const char *format, va_list args) > { > @@ -65,7 +81,7 @@ libiberty_vprintf_buffer_size (const char *format, va_list > args) > total_width += abs (va_arg (ap, int)); > } > else > - total_width += strtoul (p, (char **) &p, 10); > + total_width += do_strtoul (p, (char **) &p, 10); > if (*p == '.') > { > ++p; > @@ -75,7 +91,7 @@ libiberty_vprintf_buffer_size (const char *format, va_list > args) > total_width += abs (va_arg (ap, int)); > } > else > - total_width += strtoul (p, (char **) &p, 10); > + total_width += do_strtoul (p, (char **) &p, 10); > } > do > { > -- > 2.53.0 >
