aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-strlen.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-03-01 17:35:49 -0700
committerMartin Sebor <msebor@redhat.com>2020-03-01 17:35:49 -0700
commit1e9369c5dcf301e090d3a83e2c210cd6b96ac08c (patch)
treeffd4b9cd733424caaa4326de5dd1279eba7ca163 /gcc/tree-ssa-strlen.c
parent750d061df091da1eec2ee85e506d5291f7217ec9 (diff)
downloadgcc-1e9369c5dcf301e090d3a83e2c210cd6b96ac08c.zip
gcc-1e9369c5dcf301e090d3a83e2c210cd6b96ac08c.tar.gz
gcc-1e9369c5dcf301e090d3a83e2c210cd6b96ac08c.tar.bz2
PR middle-end/93829 - bogus -Wstringop-overflow on memcpy of a struct with a pointer member from another with a long string
gcc/testsuite/ChangeLog: PR middle-end/93829 * gcc.dg/Wstringop-overflow-32.c: New test. gcc/ChangeLog: PR middle-end/93829 * tree-ssa-strlen.c (count_nonzero_bytes): Set the size to that of a pointer in the outermost ADDR_EXPRs.
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r--gcc/tree-ssa-strlen.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 9a88a85..b76b54e 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -4587,12 +4587,15 @@ int ssa_name_limit_t::next_ssa_name (tree ssa_name)
/* 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. 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.
+ to each.
+ Sets LENRANGE[2] to the total size of the access (which may be less
+ than LENRANGE[1] when what's being referenced by EXP is a pointer
+ rather than an array).
+ Sets *NULTERM 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.
+ the size of the access to it determined from an ADDR_EXPR (i.e.,
+ a pointer) or MEM_REF or zero for other expressions.
Uses RVALS to determine range information.
Avoids recursing deeper than the limits in SNLIM allow.
Returns true on success and false otherwise. */
@@ -4692,7 +4695,13 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
}
if (TREE_CODE (exp) == ADDR_EXPR)
- exp = TREE_OPERAND (exp, 0);
+ {
+ /* If the size of the access hasn't been determined yet it's that
+ of a pointer. */
+ if (!nbytes)
+ nbytes = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (exp)));
+ exp = TREE_OPERAND (exp, 0);
+ }
if (TREE_CODE (exp) == SSA_NAME)
{
@@ -4788,9 +4797,10 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
return false;
if (!nbytes)
- /* If NBYTES hasn't been determined earlier from MEM_REF,
- set it here. It includes all internal nuls, including
- the terminating one if the string has one. */
+ /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
+ (i.e., it's the size of a pointer), or from MEM_REF (as the size
+ of the access), set it here to the size of the string, including
+ all internal and trailing nuls if the string has any. */
nbytes = nchars - offset;
prep = TREE_STRING_POINTER (exp) + offset;