diff options
author | Martin Sebor <msebor@redhat.com> | 2020-09-11 09:40:45 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-09-11 09:42:29 -0600 |
commit | f36a8168f04dfbde9d4c64421c1058975b28ff9a (patch) | |
tree | 0a91d08d1d73d3cdd55bce00bfe8474576186b89 /gcc/builtins.c | |
parent | 1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c (diff) | |
download | gcc-f36a8168f04dfbde9d4c64421c1058975b28ff9a.zip gcc-f36a8168f04dfbde9d4c64421c1058975b28ff9a.tar.gz gcc-f36a8168f04dfbde9d4c64421c1058975b28ff9a.tar.bz2 |
Move/correct offset adjustment (PR middle-end/96903).
Resolves:
PR middle-end/96903 - bogus warning on memcpy at negative offset from array end
gcc/ChangeLog:
PR middle-end/96903
* builtins.c (compute_objsize): Remove incorrect offset adjustment.
(compute_objsize): Adjust offset range here instead.
gcc/testsuite/ChangeLog:
PR middle-end/96903
* gcc.dg/Wstringop-overflow-42.c:: Add comment.
* gcc.dg/Wstringop-overflow-43.c: New test.
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 97f1a18..8b9a4a4 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4372,12 +4372,6 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, orng[0] = wi::to_offset (TYPE_MIN_VALUE (ptrdiff_type_node)); orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node)); } - else if (wi::lts_p (orng[1], orng[0])) - /* The upper bound is less than the lower bound when the integer - operand is the result of signed integer conversion to sizetype, - as in P + OFF + CST where OFF > 0. - Correct just the upper bound. */ - orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node)); pref->offrng[0] += orng[0]; pref->offrng[1] += orng[1]; @@ -4403,7 +4397,8 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, return false; } -/* Convenience wrapper around the above. */ +/* A "public" wrapper around the above. Clients should use this overload + instead. */ static tree compute_objsize (tree ptr, int ostype, access_ref *pref, @@ -4420,6 +4415,15 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, if (!success) return NULL_TREE; + if (pref->offrng[1] < pref->offrng[0]) + { + if (pref->offrng[1] < 0 + && pref->sizrng[1] <= pref->offrng[0]) + return size_zero_node; + + return wide_int_to_tree (sizetype, pref->sizrng[1]); + } + if (pref->offrng[0] < 0) { if (pref->offrng[1] < 0) @@ -4428,7 +4432,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, pref->offrng[0] = 0; } - if (pref->sizrng[1] < pref->offrng[0]) + if (pref->sizrng[1] <= pref->offrng[0]) return size_zero_node; return wide_int_to_tree (sizetype, pref->sizrng[1] - pref->offrng[0]); |