From: Jakub Jelinek Date: Tue, 3 Jan 2017 07:23:11 +0000 (+0100) Subject: re PR tree-optimization/78965 (Invalid -fprintf-return-value optimization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e1b2df8918..af5185a7e65 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-01-03 Jakub Jelinek + 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 ecd2267ae93..5bf0215cf1e 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 bdaa2fe5d68..abed28d0918 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-01-03 Jakub Jelinek + 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 00000000000..9ae1ad4a56c --- /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; +}