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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public