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

Reply via email to