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.
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
/* 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;
};
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. */
return false;
case 'n':
+ /* %n has side-effects even when nothing is actually printed to
+ any buffer. */
+ info.nowrite = false;
break;
case 'c':
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.
--- /dev/null
+/* 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;
+}