aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-01-03 08:23:11 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-01-03 08:23:11 +0100
commit51ad5d5ba376c1eaf76fee8e2457b8bfb9b000c1 (patch)
tree92fdd2f4310da70779ccbcbc42c0affad3c6ab51
parentcd123354c511316c020bf7ff7e4527989b440223 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/gimple-ssa-sprintf.c10
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/pr78965.c14
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;
+}