aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-09-11 09:40:45 -0600
committerMartin Sebor <msebor@redhat.com>2020-09-11 09:42:29 -0600
commitf36a8168f04dfbde9d4c64421c1058975b28ff9a (patch)
tree0a91d08d1d73d3cdd55bce00bfe8474576186b89 /gcc/builtins.c
parent1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c (diff)
downloadgcc-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.c20
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]);