aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-ssa-sprintf.c6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr83448.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c46
5 files changed, 77 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a948c2a..082223d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/83448
+ * gimple-ssa-sprintf.c (maybe_warn): Don't call set_caret_index
+ if navail is >= dir.len.
+
2017-12-21 Steve Ellcey <sellcey@cavium.com>
* config/aarch64/t-aarch64-linux (MULTILIB_OSDIRNAMES): Fix
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 4275755..14b1219 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -2466,7 +2466,8 @@ maybe_warn (substring_loc &dirloc, location_t argloc,
/* 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')
@@ -2594,7 +2595,8 @@ maybe_warn (substring_loc &dirloc, location_t argloc,
/* 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 a93c0dd..2f5fd08 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/83448
+ * gcc.c-torture/compile/pr83448.c: New test.
+ * gcc.dg/tree-ssa/builtin-snprintf-warn-4.c: New test.
+
2017-12-21 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/atomic9.adb: 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 0000000..9f0d9ac
--- /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 0000000..e6abf24
--- /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 "" } */
+}