[Bug c/79554] New: Zero length format string passed to fprintf under if statement causes error message

2017-02-16 Thread cnconlinux at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79554

Bug ID: 79554
   Summary: Zero length format string passed to fprintf under if
statement causes error message
   Product: gcc
   Version: 4.8.4
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cnconlinux at gmail dot com
  Target Milestone: ---

I've written a macro which throws compilation error while there is no error at
all. strcmp makes a check to avoid passing empty format string to fprintf
function, but compiler doesn't know about it because it's a macro. But even
making a pointer to constant string doesn't work.

I want gcc to check for format-security, but it must ignore such situations. If
gcc knows the value of argument, it could evaluate strcmp (both arguments are
constant strings) to check if fprint function will run.

Error message:
error: format not a string literal and no format arguments
[-Werror=format-security]

Example 1:

#define PRINT_CHANGE(fmt, args...) \
do { \
fprintf(DEBUG_STREAM, "%s(", __FUNCTION__);  \
if (strcmp(fmt, "") != 0) { \
fprintf(DEBUG_STREAM, fmt_, ##args); \
} \
fprintf(DEBUG_STREAM, ")\n"); \
} while (0)

PRINT_CHANGE("");

Example 2:

#define PRINT_CHANGE(fmt, args...) \
do { \
fprintf(DEBUG_STREAM, "%s(", __FUNCTION__);  \
const char *fmt_ = fmt;  \
if (strcmp(fmt_, "") != 0) { \
fprintf(DEBUG_STREAM, fmt_, ##args); \
} \
fprintf(DEBUG_STREAM, ")\n"); \
} while (0)

PRINT_CHANGE("");

[Bug c/79554] Zero length format string passed to fprintf under if statement causes error message

2017-02-21 Thread cnconlinux at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79554

--- Comment #3 from Андрей Доценко  ---
(In reply to Jakub Jelinek from comment #1)
> In the first macro fmt_ isn't defined at all (nor there is a fmt_ variable),
> so I doubt it compiles at all.
> And, in the second macro, the warning is 100% correct, fmt_ is a non-const
> variable, -Wformat-security is a FE warning, so can't rely on any
> optimizations etc.  Probably const char *const fmt_ = fmt; should work,
> because then it should be able to look at the var's initializer.

I've simplified the code to make this report, so I've made a mistake. The code
is meant to be:

#define PRINT_CHANGE(fmt, args...) \
do { \
fprintf(DEBUG_STREAM, "%s(", __FUNCTION__);  \
if (strcmp(fmt, "") != 0) { \
fprintf(DEBUG_STREAM, fmt, ##args); \
} \
fprintf(DEBUG_STREAM, ")\n"); \
} while (0)

PRINT_CHANGE("");