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
This commit is contained in:
Martin Sebor 2019-08-27 23:31:44 +00:00 committed by Martin Sebor
parent 2d8ba44101
commit 407b92bcfb
6 changed files with 101 additions and 5 deletions

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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, ...) \

View File

@ -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);
}

View File

@ -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;
}