PR middle-end/92026 - gcc.dg/Wstringop-overflow-18.c FAIL
authorMartin Sebor <msebor@redhat.com>
Tue, 8 Oct 2019 19:48:27 +0000 (19:48 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 8 Oct 2019 19:48:27 +0000 (13:48 -0600)
PR middle-end/92026 - gcc.dg/Wstringop-overflow-18.c FAIL
PR middle-end/92014 - bogus warning: writing 8 bytes into a region of size 1 in timezone/zic.c

gcc/ChangeLog:
* tree-ssa-strlen.c (count_nonzero_bytes): Avoid recursing for MEM_REF
again once nbytes has been set.  Set the access size when not yet set.

gcc/testsuite/ChangeLog:

PR middle-end/92014
* gcc.dg/Wstringop-overflow-19.c: New test.

From-SVN: r276711

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstringop-overflow-19.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index f82d7f5..4bf0470 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-08  Martin Sebor  <msebor@redhat.com>
+
+       PR middle-end/92026
+       PR middle-end/92014
+       * tree-ssa-strlen.c (count_nonzero_bytes): Avoid recursing for MEM_REF
+       again once nbytes has been set.  Set the access size when not yet set.
+
 2019-10-08  Iain Sandoe  <iain@sandoe.co.uk>
 
        * config/darwin.c (machopic_select_section): Remove dead code for
index cad47cc..1b6c04a 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-08  Martin Sebor  <msebor@redhat.com>
+
+       PR middle-end/92014
+       * gcc.dg/Wstringop-overflow-19.c: New test.
+
 2019-10-08  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/91801
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-19.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-19.c
new file mode 100644 (file)
index 0000000..cf866b3
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR middle-end/92014 - bogus warning: writing 8 bytes into a region
+   of size 1 in timezone/zic.c
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+struct
+{
+  char *s1, *s2;
+  char c;
+} z;
+
+
+void f (char **a, int i, int j)
+{
+  char * cp = __builtin_strchr (a[i], '%');
+
+  if (cp && *++cp != 's')
+    return;
+
+  z.s1 = __builtin_strdup (a[i]);
+  if (!z.s1) __builtin_abort ();
+
+  z.s2 = __builtin_strdup (a[j]);
+  if (!z.s2) __builtin_abort ();
+
+  z.c = cp ? *cp : '\0';    // { dg-bogus "\\\[-Wstringop-overflow" }
+}
index d68df19..c2866e0 100644 (file)
@@ -3741,13 +3741,16 @@ int ssa_name_limit_t::next_ssa_name (tree ssa_name)
   return 0;
 }
 
-/* Determine the minimum and maximum number of leading non-zero bytes
+/* Determines the minimum and maximum number of leading non-zero bytes
    in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
-   to each.  Set LENRANGE[2] to the total number of bytes in
-   the representation.  Set *NULTREM if the representation contains
-   a zero byte, and set *ALLNUL if all the bytes are zero.  Avoid
-   recursing deeper than the limits in SNLIM allow.  Return true
-   on success and false otherwise.  */
+   to each.  Sets LENRANGE[2] to the total number of bytes in
+   the representation.  Sets *NULTREM if the representation contains
+   a zero byte, and sets *ALLNUL if all the bytes are zero.
+   OFFSET and NBYTES are the offset into the representation and
+   the size of the access to it determined from a MEM_REF or zero
+   for other expressions.
+   Avoid recursing deeper than the limits in SNLIM allow.
+   Returns true on success and false otherwise.  */
 
 static bool
 count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
@@ -3769,15 +3772,13 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
        return false;
 
       len -= offset;
-      size -= offset;
-
-      if (size < nbytes)
-       return false;
 
       if (len < lenrange[0])
        lenrange[0] = len;
       if (lenrange[1] < len)
        lenrange[1] = len;
+      if (lenrange[2] < nbytes)
+       lenrange[2] = nbytes;
 
       if (!si->full_string_p)
        *nulterm = false;
@@ -3843,6 +3844,9 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
 
   if (TREE_CODE (exp) == MEM_REF)
     {
+      if (nbytes)
+       return false;
+
       tree arg = TREE_OPERAND (exp, 0);
       tree off = TREE_OPERAND (exp, 1);
 
@@ -3910,8 +3914,10 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
          lenrange[0] = 0;
          prep = NULL;
        }
-      else
+      else if (!nbytes)
        nbytes = repsize;
+      else if (nbytes < repsize)
+       return false;
     }
 
   if (!nbytes)