diff options
author | Martin Sebor <msebor@redhat.com> | 2019-08-27 23:31:44 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-08-27 17:31:44 -0600 |
commit | 407b92bcfb34f352b6aad7b629bf365c02114469 (patch) | |
tree | aae733d110df9ec932c4b6e87ca9b79a1ae4305b /gcc | |
parent | 2d8ba44101028f4be534a20a0d2146695e1dc4fd (diff) | |
download | gcc-407b92bcfb34f352b6aad7b629bf365c02114469.zip gcc-407b92bcfb34f352b6aad7b629bf365c02114469.tar.gz gcc-407b92bcfb34f352b6aad7b629bf365c02114469.tar.bz2 |
PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building glibc (32-bit only)
gcc/ChangeLog:
PR tree-optimization/91567
* gimple-ssa-sprintf.c (get_string_length): Handle more forms of lengths
of unknown strings.
* vr-values.c (vr_values::extract_range_basic): Set strlen upper bound
to PTRDIFF_MAX - 2.
gcc/testsuite/ChangeLog:
PR tree-optimization/91567
* gcc.dg/tree-ssa/builtin-snprintf-6.c: Xfail a subset of assertions
on targets other than x86_64 to work around PR 83543.
* gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: New test.
From-SVN: r274976
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/gimple-ssa-sprintf.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c | 58 | ||||
-rw-r--r-- | gcc/vr-values.c | 7 |
6 files changed, 101 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d9d6cf..1213e95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-08-27 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/91567 + * gimple-ssa-sprintf.c (get_string_length): Handle more forms of lengths + of unknown strings. + * vr-values.c (vr_values::extract_range_basic): Set strlen upper bound + to PTRDIFF_MAX - 2. + 2019-08-27 Jeff Law <law@redhat.com> * tree-ssa-strlen.c (printf_strlen_execute): Initialize diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 6a39a71..b11d798 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1994,10 +1994,21 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr) or it's SIZE_MAX otherwise. */ /* Return the default result when nothing is known about the string. */ - if (lendata.maxbound - && integer_all_onesp (lendata.maxbound) - && integer_all_onesp (lendata.maxlen)) - return fmtresult (); + if (lendata.maxbound) + { + if (integer_all_onesp (lendata.maxbound) + && integer_all_onesp (lendata.maxlen)) + return fmtresult (); + + if (!tree_fits_uhwi_p (lendata.maxbound) + || !tree_fits_uhwi_p (lendata.maxlen)) + return fmtresult (); + + unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2; + if (lenmax <= tree_to_uhwi (lendata.maxbound) + && lenmax <= tree_to_uhwi (lendata.maxlen)) + return fmtresult (); + } HOST_WIDE_INT min = (tree_fits_uhwi_p (lendata.minlen) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2560faf..cd6fb7f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-08-27 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/91567 + * gcc.dg/tree-ssa/builtin-snprintf-6.c: Xfail a subset of assertions + on targets other than x86_64 to work around PR 83543. + * gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: New test. + 2019-08-27 Jeff Law <law@redhat.com> * gcc.c-torture/compile/20190827-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c index 0d9b275..df0e6b7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c @@ -65,6 +65,10 @@ void test_assign_init_list (void) T (5, ARGS ({ 1, 2, 3, 4, 5, 6, 0 }), "s=%.*s", 3, &a[2]); } +#if __x86_64__ + +/* Enabled only on x86_64 to work around PR 83543. */ + #undef T #define T(expect, init, fmt, ...) \ do { \ @@ -87,6 +91,9 @@ void test_assign_aggregate (void) T (5, "123456", "s=%.*s", 3, &s.a[2]); } +/* { dg-final { scan-tree-dump-times "Function test_assign_aggregate" 1 "optimized" { xfail { { ! x86_64-*-* } || { ilp32 } } } } } */ + +#endif /* x86_64 */ #undef T #define T(expect, init, fmt, ...) \ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c new file mode 100644 index 0000000..6fd1bca --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c @@ -0,0 +1,58 @@ +/* PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building + glibc (32-bit only) + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +typedef __SIZE_TYPE__ size_t; + +extern int sprintf (char*, const char*, ...); +extern size_t strlen (const char*); + +void f (char *); + +void g (char *s1, char *s2) +{ + char b[1025]; + size_t n = __builtin_strlen (s1), d = __builtin_strlen (s2); + if (n + d + 1 >= 1025) + return; + + sprintf (b, "%s.%s", s1, s2); // { dg-bogus "\\\[-Wformat-overflow" } + + f (b); +} + +/* Extracted from gcc/c-cppbuiltin.c. */ + +void cpp_define (char*); + +static void +builtin_define_type_minmax (const char *min_macro, const char *max_macro, + void *type) +{ + extern const char *suffix; + char *buf; + + if (type) + { + buf = (char *) __builtin_alloca (__builtin_strlen (min_macro) + 2 + + __builtin_strlen (suffix) + 1); + sprintf (buf, "%s=0%s", min_macro, suffix); // { dg-bogus "\\\[-Wformat-overflow" } + } + else + { + buf = (char *) __builtin_alloca (__builtin_strlen (min_macro) + 3 + + __builtin_strlen (max_macro) + 6); + sprintf (buf, "%s=(-%s - 1)", min_macro, max_macro); // { dg-bogus "\\\[-Wformat-overflow" } + } + + cpp_define (buf); +} + +void +c_cpp_builtins (void *type) +{ + + builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__", type); + builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", type); +} diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 96c764c..256cae7 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1319,7 +1319,12 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) tree max = vrp_val_max (ptrdiff_type_node); wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); tree range_min = build_zero_cst (type); - tree range_max = wide_int_to_tree (type, wmax - 1); + /* To account for the terminating NUL, the maximum length + is one less than the maximum array size, which in turn + is one less than PTRDIFF_MAX (or SIZE_MAX where it's + smaller than the former type). + FIXME: Use max_object_size() - 1 here. */ + tree range_max = wide_int_to_tree (type, wmax - 2); vr->set (VR_RANGE, range_min, range_max); return; } |