https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79800
Bug ID: 79800 Summary: wrong snprintf result range with precision in a narrow negative-positive range Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- As mentioned in the patch for bug 79692 (https://gcc.gnu.org/ml/gcc-patches/2017-02/msg01564.html), the return value of a call to snprintf with a floating directive, a non-constant floating argument, and with precision specified by the asterisk whose argument's range includes both negative and non-negative values (and the upper bound is low), is in the wrong range. The following test case shows the problem. A negative precision must be treated as if no precision were specified. The result of formatting 1.23456789 using %a is 0x1.3c0ca4283de1bp+0, which is 20 bytes. However, the -fprintf-return-value optimization sets the range of the return value to [6, 15], causing the test program to print "20 < 20" when it should print "20 >= 20" instead. $ cat z.c && gcc -O2 -Wall -Wextra -Wpedantic z.c && ./a.out volatile double x = 1.23456789; void f (int p) { if (p < -1 || 0 < p) p = -1; char d[30]; int n = __builtin_sprintf (d, "%.*a", p, x); const char *s = n < 20 ? "< 20" : ">= 20"; __builtin_printf ("%i %s\n%zu: \"%s\"\n", n, s, __builtin_strlen (d), d); } volatile int i; int main () { volatile int i = -1; f (i); } 20 < 20 20: "0x1.3c0ca4283de1bp+0"