Mark _vscprintf() and _scprintf() functions with attribute pure as their return value depends only on passed arguments.
In function __ms_vsnprintf() check only for n==0 and move _vscprintf() call at the end of function. This allows LTO to optimize out _vscprintf() call from __ms_vsnprintf() function if caller of snprintf() or vsnprintf() does not use return value. It works because _vscprintf() is direct return value of __ms_vsnprintf() and function marked as pure is automatically optimized out if its return value is not used. --- mingw-w64-crt/stdio/vsnprintf.c | 10 +++++----- mingw-w64-headers/crt/stdio.h | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mingw-w64-crt/stdio/vsnprintf.c b/mingw-w64-crt/stdio/vsnprintf.c index 364186702b75..772a23f660ca 100644 --- a/mingw-w64-crt/stdio/vsnprintf.c +++ b/mingw-w64-crt/stdio/vsnprintf.c @@ -13,19 +13,19 @@ int __cdecl __ms_vsnprintf (char *s,size_t n,const char *format,va_list arg) /* _vsnprintf() does not work with zero length buffer * so count number of character by _vscprintf() call */ - if (n == 0 || !s) + if (n == 0) return _vscprintf(format, arg); retval = _vsnprintf(s, n, format, arg); + /* _vsnprintf() does not fill trailing null byte if there is not place for it */ + if (retval < 0 || (size_t)retval == n) + s[n-1] = '\0'; + /* _vsnprintf() returns negative number if buffer is too small * so count number of character by _vscprintf() call */ if (retval < 0) retval = _vscprintf(format, arg); - /* _vsnprintf() does not fill trailing null byte if there is not place for it */ - if ((size_t)retval >= n) - s[n-1] = '\0'; - return retval; } diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h index 0769e1e55cd8..12cfe2fee066 100644 --- a/mingw-w64-headers/crt/stdio.h +++ b/mingw-w64-headers/crt/stdio.h @@ -720,6 +720,7 @@ int vsnprintf (char *__stream, size_t __n, const char *__format, __builtin_va_li int __cdecl setvbuf(FILE * __restrict__ _File,char * __restrict__ _Buf,int _Mode,size_t _Size); #ifdef _UCRT __mingw_ovr + __attribute__((pure)) int __cdecl _scprintf(const char * __restrict__ _Format,...) { __builtin_va_list __ap; @@ -740,6 +741,7 @@ int vsnprintf (char *__stream, size_t __n, const char *__format, __builtin_va_li return __ret; } #else + __attribute__((pure)) _CRTIMP int __cdecl _scprintf(const char * __restrict__ _Format,...); _CRTIMP int __cdecl _snscanf(const char * __restrict__ _Src,size_t _MaxCount,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; #endif @@ -921,6 +923,7 @@ int vsprintf (char * __restrict__ __stream, const char * __restrict__ __format, #endif /* _UCRT */ #endif /* __USE_MINGW_ANSI_STDIO */ + __attribute__((pure)) _CRTIMP int __cdecl _vscprintf(const char * __restrict__ _Format,va_list _ArgList); _CRTIMP int __cdecl _set_printf_count_output(int _Value); -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public