On 01/02/2017 12:36 PM, Jakub Jelinek wrote:
Hi!
Even when we know the exact return value of a snprintf call with 0 length
(i.e. one that doesn't write anything into a buffer), there can be %n
directives in the format string that have side-effects that shouldn't be
discarded.
The following patch avoids the replacement of the snprintf call
with just the constant if there is any %n directive.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Thanks. The fix looks good to me. I would suggest to also update
the comment above the nowrite member to say something like this:
/* True for bounded functions like snprintf that specify a zero-size
buffer as a request to compute the size of output without actually
writing any. NOWRITE is cleared in response to the %n directive
which has side-effects similar to writing output. */
Martin
2017-01-02 Jakub Jelinek <ja...@redhat.com>
PR tree-optimization/78965
* gimple-ssa-sprintf.c (pass_sprintf_length::compute_format_length):
Change first argument from const call_info & to call_info &. For %n
set info.nowrite to false.
* gcc.dg/pr78965.c: New test.
--- gcc/gimple-ssa-sprintf.c.jj 2017-01-01 12:45:35.000000000 +0100
+++ gcc/gimple-ssa-sprintf.c 2017-01-02 12:09:29.902945255 +0100
@@ -131,7 +131,7 @@ public:
void handle_gimple_call (gimple_stmt_iterator*);
struct call_info;
- bool compute_format_length (const call_info &, format_result *);
+ bool compute_format_length (call_info &, format_result *);
};
bool
@@ -2357,7 +2357,7 @@ add_bytes (const pass_sprintf_length::ca
that caused the processing to be terminated early). */
bool
-pass_sprintf_length::compute_format_length (const call_info &info,
+pass_sprintf_length::compute_format_length (call_info &info,
format_result *res)
{
/* The variadic argument counter. */
@@ -2624,6 +2624,9 @@ pass_sprintf_length::compute_format_leng
return false;
case 'n':
+ /* %n has side-effects even when nothing is actually printed to
+ any buffer. */
+ info.nowrite = false;
break;
case 'c':
--- gcc/testsuite/gcc.dg/pr78965.c.jj 2017-01-02 12:12:15.959803429 +0100
+++ gcc/testsuite/gcc.dg/pr78965.c 2017-01-02 12:11:06.000000000 +0100
@@ -0,0 +1,14 @@
+/* PR tree-optimization/78965 */
+/* { dg-do run { target c99_runtime } } */
+/* { dg-options "-O2" } */
+/* { dg-add-options c99_runtime } */
+
+int
+main ()
+{
+ int a = 5, b = 6;
+ int c = __builtin_snprintf (0, 0, "a%nb%nc", &a, &b);
+ if (a + b + c != 6)
+ __builtin_abort ();
+ return 0;
+}
Jakub