From: LIU Hao Date: Mon, 9 Feb 2026 13:44:07 +0000 (+0800) Subject: libiberty: Preserve `errno` across calls to `libiberty_vprintf_buffer_size()` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=25c18a03de230bb8e53dfbafe70626e9b6e32f50;p=thirdparty%2Fgcc.git libiberty: Preserve `errno` across calls to `libiberty_vprintf_buffer_size()` The MSVCRT `strtoul()` function resets `errno` to zero upon success. On such a system, `libiberty_vprintf_buffer_size()` could clobber `errno` like this: MINGW64 ~ $ ld nonexistent.file C:\MSYS64\mingw64\bin\ld.exe: cannot find nonexistent.file: No error libiberty/ChangeLog: * vprintf-support.c (do_strtoul): New function. (libiberty_vprintf_buffer_size): Replace `strtoul` with `do_strtoul`. Signed-off-by: LIU Hao --- diff --git a/libiberty/vprintf-support.c b/libiberty/vprintf-support.c index 5a998fbf4ae..905e86b0437 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 +#include #ifdef HAVE_STRING_H #include #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 {