build: drop global suppression of -Wformat-nonliteral, fix fallouts

Extend two existing local suppressions to GCC, and add another
GCC-specific one as a replacement.

Before this patch suppressing this warning was odd with clang, because
after this option, `-Wformat=2` is used, which re-enables it.

Also:
- mprintf: minimize scope of a warning suppression.
- tests/server: suppress this warning for a system `vsnprintf()` call
  where it could trigger in C89 builds or with
  `CFLAGS=-DCURL_NO_FMT_CHECKS` set. Seen with Apple clang 17:
  ```
  curl/tests/server/util.c:114:37: warning: format string is not a string literal [-Wformat-nonliteral]
    114 |   vsnprintf(buffer, sizeof(buffer), msg, ap);
        |                                     ^~~
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:124:69: note: expanded from macro 'vsnprintf'
    124 | #define vsnprintf(str, len, ...) __vsnprintf_chk_func (str, len, 0, __VA_ARGS__)
        |                                                                     ^~~~~~~~~~~
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:81:65: note: expanded from macro '__vsnprintf_chk_func'
     81 |         __builtin___vsnprintf_chk (str, len, flag, __darwin_obsz(str), format, ap)
        |                                                                        ^~~~~~
  ```

Ref: #20363

Closes #20366
This commit is contained in:
Viktor Szakats 2026-01-20 02:52:53 +01:00
parent c1ef1876ac
commit f07a98ae11
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
6 changed files with 27 additions and 19 deletions

View file

@ -127,7 +127,6 @@ if(PICKY_COMPILER)
-Wignored-qualifiers # clang 2.8 gcc 4.3
-Wmissing-field-initializers # clang 2.7 gcc 4.1
-Wmissing-noreturn # clang 2.7 gcc 4.1
-Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0)
-Wno-padded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs
-Wno-sign-conversion # clang 2.9 gcc 4.3
-Wno-switch-default # clang 2.7 gcc 4.1 # Not used: Annoying to fix or silence

View file

@ -673,16 +673,19 @@ static bool out_double(void *userp,
*fptr = 0; /* and a final null-termination */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#endif
/* NOTE NOTE NOTE!! Not all sprintf implementations return number of
output characters */
#ifdef HAVE_SNPRINTF
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
/* !checksrc! disable LONGLINE */
/* NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) */
(snprintf)(work, BUFFSIZE, formatbuf, dnum);
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#ifdef _WIN32
/* Old versions of the Windows CRT do not terminate the snprintf output
buffer if it reaches the max size so we do that here. */
@ -691,9 +694,6 @@ static bool out_double(void *userp,
#else
/* float and double outputs do not work without snprintf support */
work[0] = 0;
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
DEBUGASSERT(strlen(work) < BUFFSIZE);
while(*work) {

View file

@ -812,7 +812,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare])
tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar"
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef])
tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral"
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes])
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [declaration-after-statement])
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align])
@ -1028,11 +1027,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [
CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef])
fi
#
dnl Only gcc 2.97 or later
if test "$compiler_num" -ge "297"; then
tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral"
fi
#
dnl Only gcc 3.0 or later
if test "$compiler_num" -ge "300"; then
dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on

View file

@ -207,13 +207,13 @@ int tool_progress_cb(void *clientp,
memset(line, '#', num);
line[num] = '\0';
curl_msnprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth);
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
curl_mfprintf(bar->out, format, line, percent);
#ifdef __clang__
#pragma clang diagnostic pop
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
}
fflush(bar->out);

View file

@ -579,9 +579,16 @@ static const char *outtime(const char *ptr, /* %time{ ... */
if(!result) {
struct tm utc;
result = curlx_gmtime(secs, &utc);
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
if(curlx_dyn_len(&format) && !result &&
strftime(output, sizeof(output), curlx_dyn_ptr(&format), &utc))
fputs(output, stream);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
curlx_dyn_free(&format);
}
ptr = end + 1;

View file

@ -111,7 +111,15 @@ void logmsg(const char *msg, ...)
now.tm_hour, now.tm_min, now.tm_sec, (long)tv.tv_usec);
va_start(ap, msg);
/* Suppress for builds where CURL_PRINTF() is not set */
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
vsnprintf(buffer, sizeof(buffer), msg, ap);
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
va_end(ap);
do {