The final patch, and the one that actually fixes 82123/81592. This replaces the final query of global range information with a query into the EVRP range analyzer and adds the new tests.
Bootstrapped and regression tested on x86_64-linux-gnu. Jeff
* gimple-ssa-sprintf.c (format_integer): Query EVRP range analyzer for range data rather than using global data. * gcc.dg/pr81592.c: New test. * gcc.dg/pr82123.c: New test. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index b3ffaec..1189d9f 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1451,12 +1451,13 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values) { /* Try to determine the range of values of the integer argument (range information is not available for pointers). */ - wide_int min, max; - enum value_range_type range_type = get_range_info (arg, &min, &max); - if (range_type == VR_RANGE) + value_range *vr = vr_values->get_value_range (arg); + if (vr->type == VR_RANGE + && TREE_CODE (vr->min) == INTEGER_CST + && TREE_CODE (vr->max) == INTEGER_CST) { - argmin = wide_int_to_tree (argtype, min); - argmax = wide_int_to_tree (argtype, max); + argmin = vr->min; + argmax = vr->max; /* Set KNOWNRANGE if the argument is in a known subrange of the directive's type and neither width nor precision @@ -1469,11 +1470,12 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values) res.argmin = argmin; res.argmax = argmax; } - else if (range_type == VR_ANTI_RANGE) + else if (vr->type == VR_ANTI_RANGE) { /* Handle anti-ranges if/when bug 71690 is resolved. */ } - else if (range_type == VR_VARYING) + else if (vr->type == VR_VARYING + || vr->type == VR_UNDEFINED) { /* The argument here may be the result of promoting the actual argument to int. Try to determine the type of the actual commit d7ab4f0e1f049f2d9bce8c5f579ce3c837bcc29c Author: Jeff Law <l...@torsion.usersys.redhat.com> Date: Tue Feb 20 13:38:48 2018 -0500 Tests diff --git a/gcc/testsuite/gcc.dg/pr81592.c b/gcc/testsuite/gcc.dg/pr81592.c new file mode 100644 index 0000000..a37703a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr81592.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -fno-strict-overflow -Wstrict-overflow=2 -fsanitize=signed-integer-overflow" } */ + +#include <stdio.h> + +int proc_keys_show(long expiry, long now) +{ + unsigned long timo; + char xbuf[4]; + + if (now < expiry) { + timo = expiry - now; + if (timo < 60) + sprintf(xbuf, "%lus", timo); + } + + return 0; +} + + diff --git a/gcc/testsuite/gcc.dg/pr82123.c b/gcc/testsuite/gcc.dg/pr82123.c new file mode 100644 index 0000000..34109f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr82123.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wformat-overflow=1" } */ + +void acpi_gpiochip_request_interrupt(unsigned short s) +{ + char name[3]; + unsigned int pin = s; + + if (pin <= 255) + __builtin_sprintf(name, "%02X", pin); +} +