From: Martin Sebor Date: Tue, 14 Feb 2017 04:38:54 +0000 (+0000) Subject: PR middle-end/79496 - call to snprintf with zero size eliminated with -Wformat-trunca... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee75687bc64b31bb3561ba77d2660f90a1be4a75;p=gcc.git PR middle-end/79496 - call to snprintf with zero size eliminated with -Wformat-truncation=2 gcc/ChangeLog: 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. gcc/testsuite/ChangeLog: PR middle-end/79496 * gcc.dg/tree-ssa/builtin-snprintf-2.c: New test. From-SVN: r245415 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b6be5d81645..2561d535a2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-02-13 Martin Sebor + + 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 * cprop.c (cprop_jump): Add missing space in string literal. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index e6cc31d1c48..b2db8b848b0 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -3443,6 +3443,10 @@ pass_sprintf_length::handle_gimple_call (gimple_stmt_iterator *gsi) 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 @@ -3483,8 +3487,8 @@ pass_sprintf_length::handle_gimple_call (gimple_stmt_iterator *gsi) 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); @@ -3495,6 +3499,11 @@ pass_sprintf_length::handle_gimple_call (gimple_stmt_iterator *gsi) ? 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; } } @@ -3511,7 +3520,7 @@ pass_sprintf_length::handle_gimple_call (gimple_stmt_iterator *gsi) 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 { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c92cff7440f..a3f66e70ff5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-02-13 Martin Sebor + + PR middle-end/79496 + * gcc.dg/tree-ssa/builtin-snprintf-2.c: New test. + 2017-02-13 Jakub Jelinek PR sanitizer/79341 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-2.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-2.c new file mode 100644 index 00000000000..a192aee605d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-2.c @@ -0,0 +1,24 @@ +/* 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"} } */