diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-01-03 08:23:11 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-01-03 08:23:11 +0100 |
commit | 51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1 (patch) | |
tree | 92fdd2f4310da70779ccbcbc42c0affad3c6ab51 | |
parent | cd123354c511316c020bf7ff7e4527989b440223 (diff) | |
download | gcc-51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1.zip gcc-51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1.tar.gz gcc-51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1.tar.bz2 |
re PR tree-optimization/78965 (Invalid -fprintf-return-value optimization)
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.
From-SVN: r244014
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/gimple-ssa-sprintf.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr78965.c | 14 |
4 files changed, 29 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e1b2df..af5185a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-01-03 Jakub Jelinek <jakub@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. + PR middle-end/78901 * gimple-ssa-sprintf.c (try_substitute_return_value): Don't change possibly throwing calls. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index ecd2267..5bf0215 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -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 @@ -710,7 +710,8 @@ struct pass_sprintf_length::call_info /* 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. */ + writing any. NOWRITE is cleared in response to the %n directive + which has side-effects similar to writing output. */ bool nowrite; }; @@ -2357,7 +2358,7 @@ add_bytes (const pass_sprintf_length::call_info &info, 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 +2625,9 @@ pass_sprintf_length::compute_format_length (const call_info &info, return false; case 'n': + /* %n has side-effects even when nothing is actually printed to + any buffer. */ + info.nowrite = false; break; case 'c': diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bdaa2fe..abed28d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-01-03 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/78965 + * gcc.dg/pr78965.c: New test. + PR middle-end/78901 * g++.dg/opt/pr78901.C: New test. diff --git a/gcc/testsuite/gcc.dg/pr78965.c b/gcc/testsuite/gcc.dg/pr78965.c new file mode 100644 index 0000000..9ae1ad4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr78965.c @@ -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; +} |