Hi!

The following patch fixes ICU miscompilation, where an initial part of a
buffer is initializer from non-zero terminated string literal (in ICU
actually from an array of non-zero chars that the FE newly turns into
non-zero terminated string literal), but the code recently added to
tree-ssa-strlen.c doesn't consider the possibility of string literals that
aren't zero terminated.

STRING_CSTs actually are always zero terminated, but if TREE_STRING_LENGTH
doesn't include the terminating character, it is just bytes.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

I was considering using strnlen, but if all STRING_CSTs are actually zero
terminated, it will mean it reads are most one further byte and on many
targets strlen is more optimized than strnlen.

2019-01-04  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/88693
        * tree-ssa-strlen.c (get_min_string_length): Don't set *full_string_p
        for STRING_CSTs that don't contain any NUL characters in the first
        TREE_STRING_LENGTH bytes.

        * gcc.c-torture/execute/pr88693.c: New test.

--- gcc/tree-ssa-strlen.c.jj    2019-01-03 09:47:28.018069413 +0100
+++ gcc/tree-ssa-strlen.c       2019-01-04 16:28:47.549196405 +0100
@@ -3232,8 +3232,9 @@ get_min_string_length (tree rhs, bool *f
 
   if (rhs && TREE_CODE (rhs) == STRING_CST)
     {
-      *full_string_p = true;
-      return strlen (TREE_STRING_POINTER (rhs));
+      HOST_WIDE_INT len = strlen (TREE_STRING_POINTER (rhs));
+      *full_string_p = len < TREE_STRING_LENGTH (rhs);
+      return len;
     }
 
   return -1;
--- gcc/testsuite/gcc.c-torture/execute/pr88693.c.jj    2019-01-04 
16:31:50.892218304 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr88693.c       2019-01-04 
16:31:09.808885630 +0100
@@ -0,0 +1,54 @@
+/* PR tree-optimization/88693 */
+
+__attribute__((noipa)) void
+foo (char *p)
+{
+  if (__builtin_strlen (p) != 9)
+    __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+quux (char *p)
+{
+  int i;
+  for (i = 0; i < 100; i++)
+    if (p[i] != 'x')
+      __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+qux (void)
+{
+  char b[100];
+  __builtin_memset (b, 'x', sizeof (b));
+  quux (b);
+}
+
+__attribute__((noipa)) void
+bar (void)
+{
+  static unsigned char u[9] = "abcdefghi";
+  char b[100];
+  __builtin_memcpy (b, u, sizeof (u));
+  b[sizeof (u)] = 0;
+  foo (b);
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+  static unsigned char u[] = { 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r' };
+  char b[100];
+  __builtin_memcpy (b, u, sizeof (u));
+  b[sizeof (u)] = 0;
+  foo (b);
+}
+
+int
+main ()
+{
+  qux ();
+  bar ();
+  baz ();
+  return 0;
+}

        Jakub

Reply via email to