aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>2019-10-08 19:48:27 +0000
committermsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>2019-10-08 19:48:27 +0000
commit0c3cdbd9a77e53296b756ba48c2c6734bb857010 (patch)
treefcb0679a35fe62400fe8291b8fae30c2ca980686
parent8e1ee63e069ca2d006501a1d36ddebaa3c096aa9 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@276711 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-19.c27
-rw-r--r--gcc/tree-ssa-strlen.c28
4 files changed, 56 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f82d7f5b26d..4bf04707b75 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cad47cc9219..1b6c04ab122 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..cf866b3f1ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-19.c
@@ -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" }
+}
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index d68df19aa82..c2866e01d70 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -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)