From b4b883cee34560fbe5f06d432804e48ed40e8e7f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 22 Dec 2017 09:54:26 +0100 Subject: [PATCH] backport: re PR c/83448 (ice in get_source_location_for_substring, at input.c:1507) Backported from mainline 2017-12-21 Jakub Jelinek PR c/83448 * gimple-ssa-sprintf.c (maybe_warn): Don't call set_caret_index if navail is >= dir.len. * gcc.c-torture/compile/pr83448.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-warn-4.c: New test. From-SVN: r255972 --- gcc/ChangeLog | 4 ++ gcc/gimple-ssa-sprintf.c | 6 ++- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.c-torture/compile/pr83448.c | 15 ++++++ .../gcc.dg/tree-ssa/builtin-snprintf-warn-4.c | 46 +++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr83448.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4ca136538a0..4cce9bc58e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,10 @@ Backported from mainline 2017-12-21 Jakub Jelinek + PR c/83448 + * gimple-ssa-sprintf.c (maybe_warn): Don't call set_caret_index + if navail is >= dir.len. + PR rtl-optimization/80747 PR rtl-optimization/83512 * cfgrtl.c (force_nonfallthru_and_redirect): When splitting diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index a4dc035d6e9..28b672133ec 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -2294,7 +2294,8 @@ maybe_warn (substring_loc &dirloc, source_range *pargrange, /* For plain character directives (i.e., the format string itself) but not others, point the caret at the first character that's past the end of the destination. */ - dirloc.set_caret_index (dirloc.get_caret_idx () + navail); + if (navail < dir.len) + dirloc.set_caret_index (dirloc.get_caret_idx () + navail); } if (*dir.beg == '\0') @@ -2423,7 +2424,8 @@ maybe_warn (substring_loc &dirloc, source_range *pargrange, /* For plain character directives (i.e., the format string itself) but not others, point the caret at the first character that's past the end of the destination. */ - dirloc.set_caret_index (dirloc.get_caret_idx () + navail); + if (navail < dir.len) + dirloc.set_caret_index (dirloc.get_caret_idx () + navail); } if (*dir.beg == '\0') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7ec67cdbac3..c547106cc1b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,10 @@ Backported from mainline 2017-12-21 Jakub Jelinek + PR c/83448 + * gcc.c-torture/compile/pr83448.c: New test. + * gcc.dg/tree-ssa/builtin-snprintf-warn-4.c: New test. + PR rtl-optimization/80747 PR rtl-optimization/83512 * gcc.dg/pr80747.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr83448.c b/gcc/testsuite/gcc.c-torture/compile/pr83448.c new file mode 100644 index 00000000000..9f0d9aca4eb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr83448.c @@ -0,0 +1,15 @@ +/* PR c/83448 */ + +char *a; +int b; + +void +foo (void) +{ + for (;;) + { + if (b < 0) + foo (); + __builtin_snprintf (a, b, "%*s", b, ""); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c new file mode 100644 index 00000000000..e6abf24c672 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c @@ -0,0 +1,46 @@ +/* PR c/83448 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wformat-truncation -fdiagnostics-show-caret" } */ + +extern int snprintf (char *, __SIZE_TYPE__, const char *, ...); + +void +foo (char *a, char *b, char *c, int d, int e) +{ + snprintf (a, 7, "abc\\\123 efg"); + /* { dg-warning "directive output truncated writing 9 bytes into a region of size 7" "" { target *-*-* } .-1 } + { dg-message ".snprintf. output 10 bytes into a destination of size 7" "note" { target *-*-* } .-2 } + { dg-begin-multiline-output "" } + snprintf (a, 7, "abc\\\123 efg"); + ~~~~~~~~~~~^~ + { dg-end-multiline-output "" } + { dg-begin-multiline-output "note" } + snprintf (a, 7, "abc\\\123 efg"); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + d &= 63; + d += 10; + snprintf (b, 7, "a%dbcdefg", d); + /* { dg-warning "'bcdefg' directive output truncated writing 6 bytes into a region of size 4" "" { target *-*-* } .-1 } + { dg-message ".snprintf. output 10 bytes into a destination of size 7" "note" { target *-*-* } .-2 } + { dg-begin-multiline-output "" } + snprintf (b, 7, "a%dbcdefg", d); + ~~~~^~ + { dg-end-multiline-output "" } + { dg-begin-multiline-output "note" } + snprintf (b, 7, "a%dbcdefg", d); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + e &= 127; + snprintf (c, 7, "a%dbcdefgh", e); + /* { dg-warning "'bcdefgh' directive output truncated writing 7 bytes into a region of size between 3 and 5" "" { target *-*-* } .-1 } + { dg-message ".snprintf. output between 10 and 12 bytes into a destination of size 7" "note" { target *-*-* } .-2 } + { dg-begin-multiline-output "" } + snprintf (c, 7, "a%dbcdefgh", e); + ~~~~~^~ + { dg-end-multiline-output "" } + { dg-begin-multiline-output "note" } + snprintf (c, 7, "a%dbcdefgh", e); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +}