+2017-02-13 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/79496
+ * gimple-ssa-sprintf.c (pass_sprintf_length::handle_gimple_call): Avoid
+ clearing info.nowrite flag when snprintf size argument is a range.
+
2017-02-13 Jakub Jelinek <jakub@redhat.com>
* cprop.c (cprop_jump): Add missing space in string literal.
info.format = gimple_call_arg (info.callstmt, idx_format);
+ /* True when the destination size is constant as opposed to the lower
+ or upper bound of a range. */
+ bool dstsize_cst_p = true;
+
if (idx_dstsize == HOST_WIDE_INT_M1U)
{
/* For non-bounded functions like sprintf, determine the size
else if (TREE_CODE (size) == SSA_NAME)
{
/* Try to determine the range of values of the argument
- and use the greater of the two at -Wformat-level 1 and
- the smaller of them at level 2. */
+ and use the greater of the two at level 1 and the smaller
+ of them at level 2. */
wide_int min, max;
enum value_range_type range_type
= get_range_info (size, &min, &max);
? wi::fits_uhwi_p (max) ? max.to_uhwi () : max.to_shwi ()
: wi::fits_uhwi_p (min) ? min.to_uhwi () : min.to_shwi ());
}
+
+ /* The destination size is not constant. If the function is
+ bounded (e.g., snprintf) a lower bound of zero doesn't
+ necessarily imply it can be eliminated. */
+ dstsize_cst_p = false;
}
}
without actually producing any. Pretend the size is
unlimited in this case. */
info.objsize = HOST_WIDE_INT_MAX;
- info.nowrite = true;
+ info.nowrite = dstsize_cst_p;
}
else
{
--- /dev/null
+/* PR middle-end/79496 - call to snprintf with non-zero size eliminated
+ with -Wformat-truncation=2
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wformat-truncation=2 -fprintf-return-value -fdump-tree-optimized" } */
+
+char d[2];
+
+int test_cst (unsigned n)
+{
+ if (1 < n)
+ n = 0;
+
+ return __builtin_snprintf (d, n, "%d", 1);
+}
+
+int test_var (char *d, unsigned n)
+{
+ if (2 < n)
+ n = 0;
+
+ return __builtin_snprintf (d, n, "%i", 1);
+}
+
+/* { dg-final { scan-tree-dump-times "snprintf" 2 "optimized"} } */