re PR c/83448 (ice in get_source_location_for_substring, at input.c:1507)
authorJakub Jelinek <jakub@redhat.com>
Thu, 21 Dec 2017 23:09:14 +0000 (00:09 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 21 Dec 2017 23:09:14 +0000 (00:09 +0100)
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: r255960

gcc/ChangeLog
gcc/gimple-ssa-sprintf.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr83448.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-4.c [new file with mode: 0644]

index a948c2ac7c3b75fe3b44bfce1a21523181181fd8..082223d5e591d78f6d8c49d6efc2d26e5071f844 100644 (file)
@@ -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
index 4275755c7bf4bb32e9e44417405e719a679e8f55..14b12191d9b16699b28541cb24914fa9f8d8fea9 100644 (file)
@@ -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')
index a93c0ddf292ceaf7b56d2dfb066853a189547ee5..2f5fd089be86487aab0b94141f65cf8652c43813 100644 (file)
@@ -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 (file)
index 0000000..9f0d9ac
--- /dev/null
@@ -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 (file)
index 0000000..e6abf24
--- /dev/null
@@ -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 "" } */
+}