From 7c3ed632601bf485335a7fe00d1db34b23ebacd2 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 8 Oct 2019 19:48:27 +0000 Subject: [PATCH] PR middle-end/92026 - gcc.dg/Wstringop-overflow-18.c FAIL 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 | 7 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/Wstringop-overflow-19.c | 27 +++++++++++++++++++ gcc/tree-ssa-strlen.c | 28 ++++++++++++-------- 4 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-19.c 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 + + 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 * 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 + + PR middle-end/92014 + * gcc.dg/Wstringop-overflow-19.c: New test. + 2019-10-08 Steven G. Kargl 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) -- 2.30.2