Commit 22fca489 by Martin Sebor Committed by Martin Sebor

PR tree-optimization/83431 - -Wformat-truncation may incorrectly report truncation

gcc/ChangeLog:

	PR c++/83431
	* gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object.
	(sprintf_dom_walker): Remove class.
	(get_int_range): Make argument const.
	(directive::fmtfunc, directive::set_precision): Same.
	(format_none): Same.
	(build_intmax_type_nodes): Same.
	(adjust_range_for_overflow): Same.
	(format_floating): Same.
	(format_character): Same.
	(format_string): Same.
	(format_plain): Same.
	(get_int_range): Cast away constness.
	(format_integer): Same.
	(get_string_length): Call get_range_strlen_dynamic.  Handle
	null lendata.maxbound.
	(should_warn_p): Adjust argument scope qualifier.
	(maybe_warn): Same.
	(format_directive): Same.
	(parse_directive): Same.
	(is_call_safe): Same.
	(try_substitute_return_value): Same.
	(sprintf_dom_walker::handle_printf_call): Rename...
	(handle_printf_call): ...to this.  Initialize target to host charmap
	here instead of in pass_sprintf_length::execute.
	(struct call_info): Make global.
	(sprintf_dom_walker::compute_format_length): Make global.
	(sprintf_dom_walker::handle_gimple_call): Same.
	* passes.def (pass_sprintf_length): Replace with pass_strlen.
	* print-rtl.c (print_pattern): Reduce the number of spaces to
	avoid -Wformat-truncation.
	* tree-pass.h (make_pass_warn_printf): New function.
	* tree-ssa-strlen.c (strlen_optimize): New variable.
	(get_string_length): Add comments.
	(get_range_strlen_dynamic): New function.
	(check_and_optimize_call): New function.
	(handle_integral_assign): New function.
	(strlen_check_and_optimize_stmt): Factor code out into
	strlen_check_and_optimize_call and handle_integral_assign.
	(strlen_dom_walker::evrp): New member.
	(strlen_dom_walker::before_dom_children): Use evrp member.
	(strlen_dom_walker::after_dom_children): Use evrp member.
	(printf_strlen_execute): New function.
	(pass_strlen::gate): Update to handle printf calls.
	(dump_strlen_info): New function.
	(pass_data_warn_printf): New variable.
	(pass_warn_printf): New class.
	* tree-ssa-strlen.h (get_range_strlen_dynamic): Declare.
	(handle_printf_call): Same.
	* tree-vrp.c (value_range_base::type): Adjust assertion.
	* vr-values.c (vr_values::update_value_range): Use type of the first
	argument rather than the second.

gcc/testsuite/ChangeLog:

	PR c++/83431
	* gcc.dg/strlenopt-63.c: New test.
	* gcc.dg/pr79538.c: Adjust text of expected warning.
	* gcc.dg/pr81292-1.c: Adjust pass name.
	* gcc.dg/pr81292-2.c: Same.
	* gcc.dg/pr81703.c: Same.
	* gcc.dg/strcmpopt_2.c: Same.
	* gcc.dg/strcmpopt_3.c: Same.
	* gcc.dg/strcmpopt_4.c: Same.
	* gcc.dg/strlenopt-1.c: Same.
	* gcc.dg/strlenopt-10.c: Same.
	* gcc.dg/strlenopt-11.c: Same.
	* gcc.dg/strlenopt-13.c: Same.
	* gcc.dg/strlenopt-14g.c: Same.
	* gcc.dg/strlenopt-14gf.c: Same.
	* gcc.dg/strlenopt-15.c: Same.
	* gcc.dg/strlenopt-16g.c: Same.
	* gcc.dg/strlenopt-17g.c: Same.
	* gcc.dg/strlenopt-18g.c: Same.
	* gcc.dg/strlenopt-19.c: Same.
	* gcc.dg/strlenopt-1f.c: Same.
	* gcc.dg/strlenopt-2.c: Same.
	* gcc.dg/strlenopt-20.c: Same.
	* gcc.dg/strlenopt-21.c: Same.
	* gcc.dg/strlenopt-22.c: Same.
	* gcc.dg/strlenopt-22g.c: Same.
	* gcc.dg/strlenopt-24.c: Same.
	* gcc.dg/strlenopt-25.c: Same.
	* gcc.dg/strlenopt-26.c: Same.
	* gcc.dg/strlenopt-27.c: Same.
	* gcc.dg/strlenopt-28.c: Same.
	* gcc.dg/strlenopt-29.c: Same.
	* gcc.dg/strlenopt-2f.c: Same.
	* gcc.dg/strlenopt-3.c: Same.
	* gcc.dg/strlenopt-30.c: Same.
	* gcc.dg/strlenopt-31g.c: Same.
	* gcc.dg/strlenopt-32.c: Same.
	* gcc.dg/strlenopt-33.c: Same.
	* gcc.dg/strlenopt-33g.c: Same.
	* gcc.dg/strlenopt-34.c: Same.
	* gcc.dg/strlenopt-35.c: Same.
	* gcc.dg/strlenopt-4.c: Same.
	* gcc.dg/strlenopt-48.c: Same.
	* gcc.dg/strlenopt-49.c: Same.
	* gcc.dg/strlenopt-4g.c: Same.
	* gcc.dg/strlenopt-4gf.c: Same.
	* gcc.dg/strlenopt-5.c: Same.
	* gcc.dg/strlenopt-50.c: Same.
	* gcc.dg/strlenopt-51.c: Same.
	* gcc.dg/strlenopt-52.c: Same.
	* gcc.dg/strlenopt-53.c: Same.
	* gcc.dg/strlenopt-54.c: Same.
	* gcc.dg/strlenopt-55.c: Same.
	* gcc.dg/strlenopt-56.c: Same.
	* gcc.dg/strlenopt-6.c: Same.
	* gcc.dg/strlenopt-61.c: Same.
	* gcc.dg/strlenopt-7.c: Same.
	* gcc.dg/strlenopt-8.c: Same.
	* gcc.dg/strlenopt-9.c: Same.
	* gcc.dg/strlenopt.h (snprintf, snprintf): Declare.
	* gcc.dg/tree-ssa/builtin-snprintf-6.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-7.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-8.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-9.c: New test.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test.
	* gcc.dg/tree-ssa/dump-4.c: New test.
	* gcc.dg/tree-ssa/pr83501.c: Adjust pass name.

From-SVN: r274933
parent 59bce4ad
2019-08-23 Martin Sebor <msebor@redhat.com>
PR c++/83431
* gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object.
(sprintf_dom_walker): Remove class.
(get_int_range): Make argument const.
(directive::fmtfunc, directive::set_precision): Same.
(format_none): Same.
(build_intmax_type_nodes): Same.
(adjust_range_for_overflow): Same.
(format_floating): Same.
(format_character): Same.
(format_string): Same.
(format_plain): Same.
(get_int_range): Cast away constness.
(format_integer): Same.
(get_string_length): Call get_range_strlen_dynamic. Handle
null lendata.maxbound.
(should_warn_p): Adjust argument scope qualifier.
(maybe_warn): Same.
(format_directive): Same.
(parse_directive): Same.
(is_call_safe): Same.
(try_substitute_return_value): Same.
(sprintf_dom_walker::handle_printf_call): Rename...
(handle_printf_call): ...to this. Initialize target to host charmap
here instead of in pass_sprintf_length::execute.
(struct call_info): Make global.
(sprintf_dom_walker::compute_format_length): Make global.
(sprintf_dom_walker::handle_gimple_call): Same.
* passes.def (pass_sprintf_length): Replace with pass_strlen.
* print-rtl.c (print_pattern): Reduce the number of spaces to
avoid -Wformat-truncation.
* tree-pass.h (make_pass_warn_printf): New function.
* tree-ssa-strlen.c (strlen_optimize): New variable.
(get_string_length): Add comments.
(get_range_strlen_dynamic): New function.
(check_and_optimize_call): New function.
(handle_integral_assign): New function.
(strlen_check_and_optimize_stmt): Factor code out into
strlen_check_and_optimize_call and handle_integral_assign.
(strlen_dom_walker::evrp): New member.
(strlen_dom_walker::before_dom_children): Use evrp member.
(strlen_dom_walker::after_dom_children): Use evrp member.
(printf_strlen_execute): New function.
(pass_strlen::gate): Update to handle printf calls.
(dump_strlen_info): New function.
(pass_data_warn_printf): New variable.
(pass_warn_printf): New class.
* tree-ssa-strlen.h (get_range_strlen_dynamic): Declare.
(handle_printf_call): Same.
* tree-vrp.c (value_range_base::type): Adjust assertion.
* vr-values.c (vr_values::update_value_range): Use type of the first
argument rather than the second.
2019-08-26 Richard Biener <rguenther@suse.de> 2019-08-26 Richard Biener <rguenther@suse.de>
* config/i386/i386-features.c (general_remove_non_convertible_regs): * config/i386/i386-features.c (general_remove_non_convertible_regs):
......
...@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_expand_omp); NEXT_PASS (pass_expand_omp);
NEXT_PASS (pass_sprintf_length, false); NEXT_PASS (pass_warn_printf);
NEXT_PASS (pass_walloca, /*strict_mode_p=*/true); NEXT_PASS (pass_walloca, /*strict_mode_p=*/true);
NEXT_PASS (pass_build_cgraph_edges); NEXT_PASS (pass_build_cgraph_edges);
TERMINATE_PASS_LIST (all_lowering_passes) TERMINATE_PASS_LIST (all_lowering_passes)
...@@ -307,7 +307,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -307,7 +307,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_lower_vector_ssa); NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_lower_switch); NEXT_PASS (pass_lower_switch);
NEXT_PASS (pass_cse_reciprocals); NEXT_PASS (pass_cse_reciprocals);
NEXT_PASS (pass_sprintf_length, true);
NEXT_PASS (pass_reassoc, false /* insert_powi_p */); NEXT_PASS (pass_reassoc, false /* insert_powi_p */);
NEXT_PASS (pass_strength_reduction); NEXT_PASS (pass_strength_reduction);
NEXT_PASS (pass_split_paths); NEXT_PASS (pass_split_paths);
...@@ -358,7 +357,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -358,7 +357,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_object_sizes); NEXT_PASS (pass_object_sizes);
/* Fold remaining builtins. */ /* Fold remaining builtins. */
NEXT_PASS (pass_fold_builtins); NEXT_PASS (pass_fold_builtins);
NEXT_PASS (pass_sprintf_length, true); NEXT_PASS (pass_strlen);
/* Copy propagation also copy-propagates constants, this is necessary /* Copy propagation also copy-propagates constants, this is necessary
to forward object-size and builtin folding results properly. */ to forward object-size and builtin folding results properly. */
NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_copy_prop);
......
...@@ -1815,7 +1815,7 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose) ...@@ -1815,7 +1815,7 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4); gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
snprintf (indented_print_rtx_head, snprintf (indented_print_rtx_head,
sizeof (indented_print_rtx_head), sizeof (indented_print_rtx_head),
"%s ", print_rtx_head); "%s ", print_rtx_head);
print_rtx_head = indented_print_rtx_head; print_rtx_head = indented_print_rtx_head;
for (int i = 0; i < seq->len (); i++) for (int i = 0; i < seq->len (); i++)
print_insn_with_notes (pp, seq->insn (i)); print_insn_with_notes (pp, seq->insn (i));
......
...@@ -79,6 +79,76 @@ ...@@ -79,6 +79,76 @@
2019-08-23 Martin Sebor <msebor@redhat.com> 2019-08-23 Martin Sebor <msebor@redhat.com>
PR c++/83431
* gcc.dg/strlenopt-63.c: New test.
* gcc.dg/pr79538.c: Adjust text of expected warning.
* gcc.dg/pr81292-1.c: Adjust pass name.
* gcc.dg/pr81292-2.c: Same.
* gcc.dg/pr81703.c: Same.
* gcc.dg/strcmpopt_2.c: Same.
* gcc.dg/strcmpopt_3.c: Same.
* gcc.dg/strcmpopt_4.c: Same.
* gcc.dg/strlenopt-1.c: Same.
* gcc.dg/strlenopt-10.c: Same.
* gcc.dg/strlenopt-11.c: Same.
* gcc.dg/strlenopt-13.c: Same.
* gcc.dg/strlenopt-14g.c: Same.
* gcc.dg/strlenopt-14gf.c: Same.
* gcc.dg/strlenopt-15.c: Same.
* gcc.dg/strlenopt-16g.c: Same.
* gcc.dg/strlenopt-17g.c: Same.
* gcc.dg/strlenopt-18g.c: Same.
* gcc.dg/strlenopt-19.c: Same.
* gcc.dg/strlenopt-1f.c: Same.
* gcc.dg/strlenopt-2.c: Same.
* gcc.dg/strlenopt-20.c: Same.
* gcc.dg/strlenopt-21.c: Same.
* gcc.dg/strlenopt-22.c: Same.
* gcc.dg/strlenopt-22g.c: Same.
* gcc.dg/strlenopt-24.c: Same.
* gcc.dg/strlenopt-25.c: Same.
* gcc.dg/strlenopt-26.c: Same.
* gcc.dg/strlenopt-27.c: Same.
* gcc.dg/strlenopt-28.c: Same.
* gcc.dg/strlenopt-29.c: Same.
* gcc.dg/strlenopt-2f.c: Same.
* gcc.dg/strlenopt-3.c: Same.
* gcc.dg/strlenopt-30.c: Same.
* gcc.dg/strlenopt-31g.c: Same.
* gcc.dg/strlenopt-32.c: Same.
* gcc.dg/strlenopt-33.c: Same.
* gcc.dg/strlenopt-33g.c: Same.
* gcc.dg/strlenopt-34.c: Same.
* gcc.dg/strlenopt-35.c: Same.
* gcc.dg/strlenopt-4.c: Same.
* gcc.dg/strlenopt-48.c: Same.
* gcc.dg/strlenopt-49.c: Same.
* gcc.dg/strlenopt-4g.c: Same.
* gcc.dg/strlenopt-4gf.c: Same.
* gcc.dg/strlenopt-5.c: Same.
* gcc.dg/strlenopt-50.c: Same.
* gcc.dg/strlenopt-51.c: Same.
* gcc.dg/strlenopt-52.c: Same.
* gcc.dg/strlenopt-53.c: Same.
* gcc.dg/strlenopt-54.c: Same.
* gcc.dg/strlenopt-55.c: Same.
* gcc.dg/strlenopt-56.c: Same.
* gcc.dg/strlenopt-6.c: Same.
* gcc.dg/strlenopt-61.c: Same.
* gcc.dg/strlenopt-7.c: Same.
* gcc.dg/strlenopt-8.c: Same.
* gcc.dg/strlenopt-9.c: Same.
* gcc.dg/strlenopt.h (snprintf, snprintf): Declare.
* gcc.dg/tree-ssa/builtin-snprintf-6.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-7.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-8.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-9.c: New test.
* gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test.
* gcc.dg/tree-ssa/dump-4.c: New test.
* gcc.dg/tree-ssa/pr83501.c: Adjust pass name.
2019-08-23 Martin Sebor <msebor@redhat.com>
* gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures
with -fpic. with -fpic.
* gcc.dg/Warray-bounds-41.c: Same. * gcc.dg/Warray-bounds-41.c: Same.
......
...@@ -17,6 +17,6 @@ void f () ...@@ -17,6 +17,6 @@ void f ()
{ {
char des[3]; char des[3];
char src[] = "abcd"; char src[] = "abcd";
__builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing up to 4 bytes into a region of size 3" } */ __builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing 4 bytes into a region of size 3" } */
return; return;
} }
...@@ -32,4 +32,4 @@ main (void) ...@@ -32,4 +32,4 @@ main (void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
...@@ -32,4 +32,4 @@ main (void) ...@@ -32,4 +32,4 @@ main (void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen1" } } */
...@@ -9,4 +9,4 @@ unsigned g (void) ...@@ -9,4 +9,4 @@ unsigned g (void)
return __builtin_strlen (d); return __builtin_strlen (d);
} }
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */ /* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */
...@@ -64,4 +64,4 @@ int main (void) ...@@ -64,4 +64,4 @@ int main (void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen" } } */ /* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen1" } } */
...@@ -28,4 +28,4 @@ int main (void) ...@@ -28,4 +28,4 @@ int main (void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen1" } } */
...@@ -13,4 +13,4 @@ f1 (S * s) ...@@ -13,4 +13,4 @@ f1 (S * s)
return result; return result;
} }
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen1" } } */
...@@ -36,9 +36,9 @@ main () ...@@ -36,9 +36,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -69,14 +69,14 @@ main () ...@@ -69,14 +69,14 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn2. */ to expand the memcpy call at the end of fn2. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen1" } } */
...@@ -58,18 +58,18 @@ main () ...@@ -58,18 +58,18 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn1. */ to expand the memcpy call at the end of fn1. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* Where the memcpy is expanded, the assignemts to elements of l are /* Where the memcpy is expanded, the assignemts to elements of l are
propagated. */ propagated. */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen" { target { avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen1" { target { avr-*-* } } } } */
...@@ -55,19 +55,19 @@ main () ...@@ -55,19 +55,19 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn1. */ to expand the memcpy call at the end of fn1. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* Where the memcpy is expanded, the assignemts to elements of l are /* Where the memcpy is expanded, the assignemts to elements of l are
propagated. */ propagated. */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen" { target { avr-*-* } } } } */ /* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen1" { target { avr-*-* } } } } */
...@@ -107,10 +107,10 @@ main () ...@@ -107,10 +107,10 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */
...@@ -11,15 +11,15 @@ ...@@ -11,15 +11,15 @@
/* Compared to strlenopt-14gf.c, strcpy_chk with string literal as /* Compared to strlenopt-14gf.c, strcpy_chk with string literal as
second argument isn't being optimized by builtins.c into second argument isn't being optimized by builtins.c into
memcpy. */ memcpy. */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */
...@@ -51,9 +51,9 @@ main () ...@@ -51,9 +51,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -24,10 +24,10 @@ main () ...@@ -24,10 +24,10 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */
...@@ -47,10 +47,10 @@ main () ...@@ -47,10 +47,10 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */
...@@ -73,9 +73,9 @@ main () ...@@ -73,9 +73,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */
...@@ -72,9 +72,9 @@ main () ...@@ -72,9 +72,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
#define FORTIFY_SOURCE 2 #define FORTIFY_SOURCE 2
#include "strlenopt-1.c" #include "strlenopt-1.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -40,9 +40,9 @@ main () ...@@ -40,9 +40,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -86,9 +86,9 @@ main () ...@@ -86,9 +86,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -57,9 +57,9 @@ main () ...@@ -57,9 +57,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -31,9 +31,9 @@ main () ...@@ -31,9 +31,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#define USE_GNU #define USE_GNU
#include "strlenopt-22.c" #include "strlenopt-22.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */
...@@ -13,4 +13,4 @@ main () ...@@ -13,4 +13,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -14,4 +14,4 @@ main () ...@@ -14,4 +14,4 @@ main ()
return len - len2; return len - len2;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -20,5 +20,5 @@ main (void) ...@@ -20,5 +20,5 @@ main (void)
return fn1 (p, q); return fn1 (p, q);
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
...@@ -19,4 +19,4 @@ main (void) ...@@ -19,4 +19,4 @@ main (void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -56,4 +56,4 @@ main () ...@@ -56,4 +56,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -24,4 +24,4 @@ main () ...@@ -24,4 +24,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
#define FORTIFY_SOURCE 2 #define FORTIFY_SOURCE 2
#include "strlenopt-2.c" #include "strlenopt-2.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -53,12 +53,12 @@ main () ...@@ -53,12 +53,12 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 0" 3 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 0" 3 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 4" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 4" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 3" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 3" 1 "optimized" } } */
...@@ -60,4 +60,4 @@ _Bool f7(char *s) ...@@ -60,4 +60,4 @@ _Bool f7(char *s)
return (t1 == s); return (t1 == s);
} }
/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
#define USE_GNU #define USE_GNU
#include "strlenopt-31.c" #include "strlenopt-31.c"
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen" } } */ /* { dg-final { scan-tree-dump-not "strlen \\(" "strlen1" } } */
...@@ -190,4 +190,4 @@ main () ...@@ -190,4 +190,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
...@@ -39,4 +39,4 @@ main () ...@@ -39,4 +39,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
...@@ -40,5 +40,5 @@ main () ...@@ -40,5 +40,5 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */
...@@ -35,4 +35,4 @@ main () ...@@ -35,4 +35,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
...@@ -28,4 +28,4 @@ main () ...@@ -28,4 +28,4 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
...@@ -66,9 +66,9 @@ main () ...@@ -66,9 +66,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -31,5 +31,5 @@ void h (void) ...@@ -31,5 +31,5 @@ void h (void)
abort(); abort();
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */
...@@ -45,7 +45,7 @@ int cmp88 (void) ...@@ -45,7 +45,7 @@ int cmp88 (void)
return cmp88; return cmp88;
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "len0 = 0;" 1 "gimple" } } { dg-final { scan-tree-dump-times "len0 = 0;" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "len = 18;" 1 "gimple" } } { dg-final { scan-tree-dump-times "len = 18;" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "lenx = 8;" 1 "gimple" } } { dg-final { scan-tree-dump-times "lenx = 8;" 1 "gimple" } }
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#define USE_GNU #define USE_GNU
#include "strlenopt-4.c" #include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
#define FORTIFY_SOURCE 2 #define FORTIFY_SOURCE 2
#include "strlenopt-4.c" #include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */
...@@ -48,9 +48,9 @@ main () ...@@ -48,9 +48,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -112,5 +112,5 @@ void test_array_ref (void) ...@@ -112,5 +112,5 @@ void test_array_ref (void)
T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0); T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0);
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */
...@@ -84,4 +84,4 @@ void test_elim_a9_9 (unsigned i) ...@@ -84,4 +84,4 @@ void test_elim_a9_9 (unsigned i)
T (0); T (1); T (2); T (3); T (4); T (5); T (6); T (7); T (8); T (0); T (1); T (2); T (3); T (4); T (5); T (6); T (7); T (8);
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } */ /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } */
...@@ -284,5 +284,5 @@ void test_global_struct_struct_array (void) ...@@ -284,5 +284,5 @@ void test_global_struct_struct_array (void)
T (ssa[5].sa9[3].a6, 3); T (ssa[5].sa9[3].a6, 3);
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */
...@@ -112,5 +112,5 @@ void test_array_ref (void) ...@@ -112,5 +112,5 @@ void test_array_ref (void)
T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0); T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0);
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */
...@@ -105,5 +105,5 @@ void elim_after_init_memcpy (void) ...@@ -105,5 +105,5 @@ void elim_after_init_memcpy (void)
T ("AB\000CD", 0, "ab\000c", 4, 2); T ("AB\000CD", 0, "ab\000c", 4, 2);
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */
...@@ -224,7 +224,7 @@ const void test_large_string_size (void) ...@@ -224,7 +224,7 @@ const void test_large_string_size (void)
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */
...@@ -45,6 +45,6 @@ void test_contents (void) ...@@ -45,6 +45,6 @@ void test_contents (void)
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } /* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */
...@@ -77,9 +77,9 @@ main () ...@@ -77,9 +77,9 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
...@@ -215,4 +215,4 @@ void test_ta2 (void) ...@@ -215,4 +215,4 @@ void test_ta2 (void)
} }
/* { dg-final { scan-tree-dump-not "failure" "optimized" } } /* { dg-final { scan-tree-dump-not "failure" "optimized" } }
{ dg-final { scan-tree-dump-not "strlen" "gimple" } } */ { dg-final { scan-tree-dump-not "strlen1" "gimple" } } */
/* PR tree-optimization/83431 - Verify that snprintf (0, 0, "%s",
with an argument that's a conditional expression evaluates to
the expected result regardless of the order of the expression
operands.
{ dg-do run }
{ dg-options "-O2 -Wall" } */
#include "strlenopt.h"
#define A(expr) \
((expr) \
? (void)0 \
: (__builtin_printf ("assertion failed on line %i: %s\n", \
__LINE__, #expr), \
__builtin_abort ()))
const char gs0[] = "";
const char gs3[] = "123";
char gc;
char ga5[7];
struct S { char n, ma7[7], max[]; };
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
/* Similar to the above but with memcpy creating a string at least
four characters long, and the address of the NUL character. */
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
int main (void)
{
equal_4_gs0_gs3_ga5_m1 (-1);
equal_4_gs0_gs3_ga5_0 ( 0);
equal_4_gs0_gs3_ga5_p1 (+1);
equal_4_gs0_ga5_gs3_m1 (-1);
equal_4_gs0_ga5_gs3_0 ( 0);
equal_4_gs0_ga5_gs3_p1 (+1);
equal_4_ga5_gs0_gs3_m1 (-1);
equal_4_ga5_gs0_gs3_0 ( 0);
equal_4_ga5_gs0_gs3_p1 (+1);
equal_4_ga5_gs3_gs0_m1 (-1);
equal_4_ga5_gs3_gs0_0 ( 0);
equal_4_ga5_gs3_gs0_p1 (+1);
equal_4_gs3_gs0_ga5_m1 (-1);
equal_4_gs3_gs0_ga5_0 ( 0);
equal_4_gs3_gs0_ga5_p1 (+1);
/* Same as aabove but with memcpy creating a string at least four
characters long. */
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_p1 (+1);
}
...@@ -40,12 +40,12 @@ main () ...@@ -40,12 +40,12 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 3;" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 3;" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */
...@@ -98,10 +98,10 @@ main () ...@@ -98,10 +98,10 @@ main ()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */ /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */
/* This is a replacement of needed parts from stdlib.h and string.h /* This is a replacement of needed parts from <stdlib.h> and <string.h>
for -foptimize-strlen testing, to ensure we are testing the builtins for -foptimize-strlen testing, to ensure we are testing the builtins
rather than whatever the OS has in its headers. */ rather than whatever the OS has in its headers. */
...@@ -25,6 +25,9 @@ void *mempcpy (void *__restrict, const void *__restrict, size_t); ...@@ -25,6 +25,9 @@ void *mempcpy (void *__restrict, const void *__restrict, size_t);
char *stpcpy (char *__restrict, const char *__restrict); char *stpcpy (char *__restrict, const char *__restrict);
#endif #endif
int sprintf (char * __restrict, const char *__restrict, ...);
int snprintf (char * __restrict, size_t, const char *__restrict, ...);
#if defined(FORTIFY_SOURCE) && FORTIFY_SOURCE > 0 && __OPTIMIZE__ #if defined(FORTIFY_SOURCE) && FORTIFY_SOURCE > 0 && __OPTIMIZE__
# define bos(ptr) __builtin_object_size (ptr, FORTIFY_SOURCE > 0) # define bos(ptr) __builtin_object_size (ptr, FORTIFY_SOURCE > 0)
# define bos0(ptr) __builtin_object_size (ptr, 0) # define bos0(ptr) __builtin_object_size (ptr, 0)
......
/* Test to verify that snprintf can determine the length of a dynamically
constructed string argument and fold the result into a constant.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
char* strcpy (char * restrict, const char * restrict);
int sprintf (char * restrict, const char *restrict, ...);
int snprintf (char * restrict, size_t, const char *restrict, ...);
#define CONCAT(x, y) x ## y
#define CAT(x, y) CONCAT (x, y)
#define FAILNAME(name, counter) \
CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter)
#define FAIL(name, counter) do { \
extern void FAILNAME (name, counter) (void); \
FAILNAME (name, counter)(); \
} while (0)
/* Macro to emit a call to funcation named
call_in_true_branch_not_eliminated_on_line_NNN()
for each call that's expected to be eliminated. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that no such call appears in output. */
#define ELIM(expr) \
if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0
#define ARGS(...) __VA_ARGS__
#define T(expect, init, fmt, ...) \
do { \
char a[] = init; \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a non-const local char array initialized by a string literal. */
void test_assign_string (void)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
/* Exercise a non-const local char array initialized by an initializer
list. */
void test_assign_init_list (void)
{
T (0, ARGS ({ 0 }), "%s", a);
T (1, ARGS ({ 1, 0 }), "%s", a);
T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3 }), "%s", a);
T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3, [4] = 0 }), "%s", a);
T (4, ARGS ({ 1, 2, 3, 4, 0 }), "%s", a);
T (5, ARGS ({ 1, 2, 3, 0 }), "s=%s", a);
T (5, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 1);
T (2, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 4);
T (5, ARGS ({ 1, 2, 3, 4, 5, 0 }), "s=%s", &a[2]);
T (5, ARGS ({ 1, 2, 3, 4, 5, 6, 0 }), "s=%.*s", 3, &a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
struct { int n; char a[sizeof init]; } \
s = { sizeof init, init }; \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a non-const local struct initialized by an initializer
list. */
void test_assign_aggregate (void)
{
T (0, "", "%s", s.a);
T (1, "1", "%s", s.a);
T (4, "1234", "%s", s.a);
T (5, "123", "s=%s", s.a);
T (5, "1234", "s=%s", s.a + 1);
T (2, "1234", "s=%s", s.a + 4);
T (5, "12345", "s=%s", &s.a[2]);
T (5, "123456", "s=%.*s", 3, &s.a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
char a[sizeof init]; \
strcpy (a, init); \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a local char array initialized by a call to strcpy. */
void test_local_strcpy (void)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (2, "12", "%s", a);
T (3, "123", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
char a[n]; \
strcpy (a, init); \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a VLA initialized by a call to strcpy. */
void test_vla_strcpy (unsigned n)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (2, "12", "%s", a);
T (3, "123", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
/* { dg-final { scan-tree-dump-times "printf" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "not_eliminated" 0 "optimized" } } */
/* Test to verify that snprintf can determine the correct range
of lengths of dynamically constructed string arguments.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
void* memcpy (void*, const void*, size_t);
char* strcpy (char * restrict, const char * restrict);
int snprintf (char * restrict, size_t, const char *restrict, ...);
void sink (void*, ...);
#define CONCAT(x, y) x ## y
#define CAT(x, y) CONCAT (x, y)
#define FAILNAME(name, counter) \
CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter)
#define FAIL(name, counter) do { \
extern void FAILNAME (name, counter) (void); \
FAILNAME (name, counter)(); \
} while (0)
/* Macro to emit a call to funcation named
call_in_true_branch_not_eliminated_on_line_NNN()
for each call that's expected to be eliminated. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that no such call appears in output. */
#define VERIFY_ELIM(expr) \
if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0
/* Macro to emit a call to a function named
call_made_in_{true,false}_branch_on_line_NNN()
for each call that's expected to be retained. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that the expected number of both kinds of calls appears in output
(a pair for each line with the invocation of the KEEP() macro. */
#define VERIFY_KEEP(expr) \
if (expr) \
FAIL (made_in_true_branch, __COUNTER__); \
else \
FAIL (made_in_false_branch, __COUNTER__)
#define ARGS(...) __VA_ARGS__
/* Each test macro expands to a new function to get around bug 81776
- missing sprintf optimization due to pointer escape analysis. */
#define ELIM(expect, dst, init, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(void) \
{ \
memcpy (dst, init, sizeof (init) - 1); \
const int res = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_ELIM (expect res); \
} typedef void dummy_typedef
#define KEEP(expect, dst, init, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(void) \
{ \
memcpy (dst, init, sizeof (init) - 1); \
const int ret = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_KEEP (expect ret); \
} typedef void dummy_typedef
/* Verify that conditions involving snprintf calls with a string
of some minimum but otherwise unbounded length stored in an array
of unknown bound are not folded unless the format string itself
restricts the maximum. The string could be longer than INT_MAX
making the snprintf call fail and return a negative value. */
extern char gax[];
KEEP (1 <=, gax, "1", "%s", gax);
KEEP (2 <=, gax, "12", "%s", gax);
KEEP (3 <=, gax, "123", "%s", gax);
ELIM (3 ==, gax, "123", "%.3s", gax);
ELIM (5 ==, gax, "123", "%.3s%.2s", gax, gax);
/* Disabled. The global pointer passed to memcpy as the destination
might point at itself, i.e., gptr == &gptr is a valid argument to
memcpy.
extern char *gptr;
KEEP (1 <=, gptr, "1", "%s", gptr);
KEEP (2 <=, gptr, "12", "%s", gptr);
KEEP (3 <=, gptr, "123", "%s", gptr);
ELIM (3 ==, gptr, "123", "%.3s", gptr);
ELIM (5 ==, gptr, "123", "%.3s%.2s", gptr, gptr);
*/
/* Verify that conditions involving snprintf calls with a string
of some minimum but otherwise unbounded length stored in an array
of a known bound are folded. The longest string that can be
stored in such arrays is bounded by the size of the array. */
extern char ga4[4];
ELIM (0 <=, ga4, "\0", "%s", ga4);
ELIM (3 >=, ga4, "\0", "%s", ga4);
ELIM (1 <=, ga4, "1", "%s", ga4);
ELIM (0 <=, ga4, "1", "%s", ga4 + 1);
ELIM (0 <=, ga4, "1", "%s", &ga4[1]);
ELIM (3 >=, ga4, "1", "%s", ga4);
ELIM (2 >=, ga4, "1", "%s", ga4 + 1);
ELIM (2 >=, ga4, "1", "%s", &ga4[1]);
ELIM (2 <=, ga4, "12", "%s", ga4);
ELIM (3 >=, ga4, "12", "%s", ga4);
ELIM (3 <=, ga4, "123", "%s", ga4);
ELIM (3 ==, ga4, "123", "%.3s", ga4);
ELIM (5 ==, ga4, "123", "%.3s%.2s", ga4, ga4);
/* Verify conditionals involving dynamically created strings of known
length stored in local arrays. */
#undef ELIM
#define ELIM(expect, N1, N2, init1, init2, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(int i) \
{ \
char a1[N1], a2[N2]; \
memcpy (a1, init1, sizeof (init1) - 1); \
memcpy (a2, init2, sizeof (init2) - 1); \
const int res = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_ELIM (expect res); \
} typedef void dummy_typedef
ELIM (0 ==, 2, 2, "\0", "\0", "%s", i ? a1 : a2);
ELIM (2 ==, 2, 2, "\0", "\0", "s=%s", i ? a1 : a2);
ELIM (1 ==, 2, 2, "a\0", "b\0", "%s", i ? a1 : a2);
ELIM (3 ==, 2, 2, "a\0", "b\0", "s=%s", i ? a1 : a2);
ELIM (2 ==, 3, 5, "ab\0", "cd\0", "%s", i ? a1 : a2);
ELIM (3 ==, 3, 5, "ab\0", "cd\0", "%3s", i ? a1 : a2);
ELIM (3 ==, 5, 5, "abcd\0", "efgh\0", "%.3s", i ? a1 : a2);
ELIM (3 ==, 4, 1, "abc\0", "", "%s", i ? a1 : "def");
ELIM (4 ==, 1, 5, "", "efgh\0", "%s", i ? "abcd" : a2);
ELIM (4 ==, 5, 5, "abcd\0", "efgh\0", "%s", i < 0 ? a1 : 0 < i ? a2 : "ijkl");
/* { dg-final { scan-tree-dump-times "_not_eliminated" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "call_made_" 6 "optimized" } } */
/* Test to verify that snprintf can determine the correct range
of lengths of string arguments based on the results of prior
calls to strlen.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
void abort (void);
size_t strlen (const char *);
int snprintf (char * restrict, size_t, const char *restrict, ...);
void one_str_exact (const char *str)
{
if (1 == strlen (str))
if (1 != snprintf (0, 0, "%s", str))
abort ();
}
void two_str_exact (const char *s1, const char *s2)
{
if (1 == strlen (s1) && 2 == strlen (s2))
if (3 != snprintf (0, 0, "%s%s", s1, s2))
abort ();
}
void one_str_maxlen (const char *str)
{
if (2 >= strlen (str))
if (2 < snprintf (0, 0, "%s", str))
abort ();
}
void two_str_maxlen (const char *s1, const char *s2)
{
if (2 >= strlen (s1) && 3 >= strlen (s2))
if (5 < snprintf (0, 0, "%s%s", s1, s2))
abort ();
}
/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
/* Test to verify that --param ssa_name_def_chain_limit can be used to
limit the maximum number of SSA_NAME assignments the built-in code
follows to determine the variable value/string length.
{ dg-do compile }
{ dg-options "-O2 -Wall --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */
void abort (void);
int sprintf (char * restrict, const char *restrict, ...);
void sink (const char*, ...);
const char a0[] = "";
const char a1[] = "1";
const char a2[] = "12";
const char a3[] = "123";
const char a4[] = "1234";
const char a5[] = "12345";
const char a6[] = "123456";
const char a7[] = "1234567";
const char a8[] = "12345678";
const char a9[] = "123456789";
int i0, i1, i2, i3, i4, i5, i6, i7, i8;
void g1 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
sink (p0, p1);
if (sprintf (d, "%s", p1) > 2)
abort ();
}
void g2 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
sink (p0, p1, p2);
if (sprintf (d, "%s", p2) > 3)
abort ();
}
void g3 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
sink (p0, p1, p2, p3);
if (sprintf (d, "%s", p3) > 4)
abort ();
}
void g4 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
sink (p0, p1, p2, p3, p4);
// p4 below is the result of the following five PHI assignments
// and with the limit set to 4 the sprintf call result is not
// determined:
// iftmp.0_7 = PHI <&a0(2), &a1(3)>
// iftmp.2_8 = PHI <iftmp.0_7(4), &a2(5)>
// iftmp.4_9 = PHI <iftmp.2_8(6), &a3(7)>
// iftmp.6_10 = PHI <iftmp.4_9(8), &a4(9)>
// iftmp.8_17 = PHI <iftmp.6_10(10), &a5(11)>
// p4 = iftmp.8_17
extern void keep_g4 (void);
if (sprintf (d, "%s", p4) > 5)
keep_g4 ();
}
void g5 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
sink (p0, p1, p2, p3, p4, p5);
extern void keep_g5 (void);
if (sprintf (d, "%s", p5) > 6)
keep_g5 ();
/* { dg-final { scan-tree-dump-times "keep_g5" 1 "optimized" } } */
}
void g6 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
sink (p0, p1, p2, p3, p4, p5, p6);
extern void keep_g6 (void);
if (sprintf (d, "%s", p6) > 7)
keep_g6 ();
/* { dg-final { scan-tree-dump-times "keep_g6" 1 "optimized" } } */
}
void g7 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
sink (p0, p1, p2, p3, p4, p5, p6, p7);
extern void keep_g7 (void);
if (sprintf (d, "%s", p7) > 8)
keep_g7 ();
/* { dg-final { scan-tree-dump-times "keep_g7" 1 "optimized" } } */
}
void g8 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
const char *p8 = i8 ? p7 : a9;
sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
extern void keep_g8 (void);
if (sprintf (d, "%s", p8) > 9)
keep_g8 ();
/* { dg-final { scan-tree-dump-times "keep_g8" 1 "optimized" } } */
}
/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
/* Test to verify that --param ssa_name_def_chain_limit can be used to
limit the maximum number of SSA_NAME assignments the built-in code
follows.
{ dg-do compile }
{ dg-options "-O2 -Wall -Wformat-truncation=2 --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
int snprintf (char * restrict, size_t, const char *restrict, ...);
void sink (const char*, ...);
const char a0[] = "";
const char a1[] = "1";
const char a2[] = "12";
const char a3[] = "123";
const char a4[] = "1234";
const char a5[] = "12345";
const char a6[] = "123456";
const char a7[] = "1234567";
const char a8[] = "12345678";
const char a9[] = "123456789";
int i0, i1, i2, i3, i4, i5, i6, i7, i8;
void g1 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
sink (p0, p1);
snprintf (d, 1, "%s", p1); // { dg-warning "\\\[-Wformat-truncation" }
}
void g2 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
sink (p0, p1, p2);
snprintf (d, 2, "%s", p2); // { dg-warning "\\\[-Wformat-truncation" }
}
void g3 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
sink (p0, p1, p2, p3);
snprintf (d, 3, "%s", p3); // { dg-warning "\\\[-Wformat-truncation" }
}
void g4 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
sink (p0, p1, p2, p3, p4);
// p4 below is the result of the following five PHI assignments
// and with the limit set to 4 the snprintf call is not diagnosed
// iftmp.0_7 = PHI <&a0(2), &a1(3)>
// iftmp.2_8 = PHI <iftmp.0_7(4), &a2(5)>
// iftmp.4_9 = PHI <iftmp.2_8(6), &a3(7)>
// iftmp.6_10 = PHI <iftmp.4_9(8), &a4(9)>
// iftmp.8_17 = PHI <iftmp.6_10(10), &a5(11)>
// p4 = iftmp.8_17
snprintf (d, 4, "%s", p4);
}
void g5 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
sink (p0, p1, p2, p3, p4, p5);
snprintf (d, 5, "%s", p5);
}
void g6 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
sink (p0, p1, p2, p3, p4, p5, p6);
snprintf (d, 6, "%s", p6);
}
void g7 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
sink (p0, p1, p2, p3, p4, p5, p6, p7);
snprintf (d, 7, "%s", p7);
}
void g8 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
const char *p8 = i8 ? p7 : a9;
sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
snprintf (d, 8, "%s", p8);
}
/* PR tree-optimization/83431 -Wformat-truncation may incorrectly report
truncation
{ dg-do compile }
{ dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
extern int snprintf (char*, size_t, const char*, ...);
extern char* strcpy (char*, const char*);
struct S
{
char a9[9];
char a5[5];
int x;
};
void test_assign_nowarn (struct S* s)
{
int i = 0;
{
char a9[9] = "1234";
snprintf (s[i].a5, sizeof (s[i].a5), "%s", a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a8[8] = "123";
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", a8); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a7[7] = "12";
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", a7); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a6[6] = "1";
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", a6); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
}
void test_strcpy_nowarn (struct S* s)
{
int i = 0;
strcpy (s[i].a9, "1234");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9);
++i;
strcpy (s[i].a9, "123");
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
++i;
strcpy (s[i].a9, "12");
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
++i;
strcpy (s[i].a9, "1");
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
void test_warn (struct S* s)
{
int i = 0;
strcpy (s[i].a9, "12345678");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 8 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "1234567");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 7 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "123456");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 6 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "12345");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'snprintf' output truncated before the last format character" } */
++i;
strcpy (s[i].a9, "1234");
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-warning "output truncated before the last format character" } */
++i;
strcpy (s[i].a9, "123");
snprintf (s[i].a5, sizeof (s[i].a5), ">%s<", s[i].a9); /* { dg-warning "output truncated before the last format character" } */
}
/* PR middle-end/87052 - STRING_CST printing incomplete in Gimple dumps
{ dg-do compile }
{ dg-options "-fdump-tree-original" } */
void* f (char *d, int c)
{
return __builtin_memchr ("1\0\0", c, 4);
}
/* Veriy the full string appears in the dump:
{ dg-final { scan-tree-dump "\"1\\\\x00\\\\x00\"" "original" } } */
...@@ -11,4 +11,4 @@ void f (void) ...@@ -11,4 +11,4 @@ void f (void)
__builtin_abort (); __builtin_abort ();
} }
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */ /* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */
...@@ -12,4 +12,4 @@ void f3 (void) ...@@ -12,4 +12,4 @@ void f3 (void)
f (__builtin_strlen (s)); f (__builtin_strlen (s));
} }
/* { dg-final { scan-tree-dump-times "strlen" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strlen" 0 "strlen1" } } */
...@@ -419,6 +419,7 @@ extern gimple_opt_pass *make_pass_omp_target_link (gcc::context *ctxt); ...@@ -419,6 +419,7 @@ extern gimple_opt_pass *make_pass_omp_target_link (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_oacc_device_lower (gcc::context *ctxt); extern gimple_opt_pass *make_pass_oacc_device_lower (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_omp_device_lower (gcc::context *ctxt); extern gimple_opt_pass *make_pass_omp_device_lower (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt); extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_warn_printf (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt); extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_fold_builtins (gcc::context *ctxt); extern gimple_opt_pass *make_pass_fold_builtins (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_post_ipa_warn (gcc::context *ctxt); extern gimple_opt_pass *make_pass_post_ipa_warn (gcc::context *ctxt);
......
...@@ -25,4 +25,11 @@ extern bool is_strlen_related_p (tree, tree); ...@@ -25,4 +25,11 @@ extern bool is_strlen_related_p (tree, tree);
extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree); extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE); extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
struct c_strlen_data;
class vr_values;
extern void get_range_strlen_dynamic (tree , c_strlen_data *, const vr_values *);
/* APIs internal to strlen pass. Defined in in gimple-ssa-sprintf.c. */
extern bool handle_printf_call (gimple_stmt_iterator *, const vr_values *);
#endif // GCC_TREE_SSA_STRLEN_H #endif // GCC_TREE_SSA_STRLEN_H
...@@ -369,7 +369,7 @@ value_range_base::singleton_p (tree *result) const ...@@ -369,7 +369,7 @@ value_range_base::singleton_p (tree *result) const
tree tree
value_range_base::type () const value_range_base::type () const
{ {
gcc_assert (m_min || undefined_p ()); gcc_assert (m_min);
return TREE_TYPE (min ()); return TREE_TYPE (min ());
} }
......
...@@ -234,7 +234,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) ...@@ -234,7 +234,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
called, if we are anyway, keep it VARYING. */ called, if we are anyway, keep it VARYING. */
if (old_vr->varying_p ()) if (old_vr->varying_p ())
{ {
new_vr->set_varying (new_vr->type ()); new_vr->set_varying (TREE_TYPE (var));
is_new = false; is_new = false;
} }
else if (new_vr->undefined_p ()) else if (new_vr->undefined_p ())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment