aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-06-18 12:00:36 -0600
committerMartin Sebor <msebor@redhat.com>2020-06-18 12:00:36 -0600
commit5acc654e380797bbf402bc3a0a67f9a6ac4c2a83 (patch)
treeaa5840bf7987db25de59013cc4e64b6bfb701ce2 /gcc/builtins.c
parent5421fae8b17c7401f3a4ac5b9f414a47f7bda379 (diff)
downloadgcc-5acc654e380797bbf402bc3a0a67f9a6ac4c2a83.zip
gcc-5acc654e380797bbf402bc3a0a67f9a6ac4c2a83.tar.gz
gcc-5acc654e380797bbf402bc3a0a67f9a6ac4c2a83.tar.bz2
Avoid warning for memset writing over multiple members.
Resolves: PR middle-end/95667 - unintended warning for memset writing across multiple members PR middle-end/92814 - missing -Wstringop-overflow writing into a dynamically allocated flexible array member gcc/ChangeLog: PR middle-end/95667 PR middle-end/92814 * builtins.c (compute_objsize): Remove call to compute_builtin_object_size and instead compute conservative sizes directly here. gcc/testsuite/ChangeLog: PR middle-end/95667 PR middle-end/92814 * gcc.dg/Wstringop-overflow-25.c: Remove xfails. * gcc.dg/Wstringop-overflow-39.c: New test.
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c48
1 files changed, 18 insertions, 30 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index caab188..4754602 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -4009,31 +4009,6 @@ static bool
compute_objsize (tree ptr, int ostype, access_ref *pref,
bitmap *visited, const vr_values *rvals /* = NULL */)
{
- if (ostype == 0)
- {
- /* Use BOS only for raw memory functions like memcpy to get
- the size of the largest enclosing object. */
- tree off = NULL_TREE;
- unsigned HOST_WIDE_INT size;
- if (compute_builtin_object_size (ptr, ostype, &size, &pref->ref, &off))
- {
- if (off)
- {
- offset_int offset = wi::to_offset (off);
- pref->offrng[0] += offset;
- pref->offrng[1] += offset;
-
- /* compute_builtin_object_size() returns the remaining
- size in PTR. Add the offset to it to get the full
- size. */
- pref->sizrng[0] = pref->sizrng[1] = size + offset;
- }
- else
- pref->sizrng[0] = pref->sizrng[1] = size;
- return true;
- }
- }
-
const bool addr = TREE_CODE (ptr) == ADDR_EXPR;
if (addr)
ptr = TREE_OPERAND (ptr, 0);
@@ -4058,18 +4033,28 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
if (code == COMPONENT_REF)
{
+ tree field = TREE_OPERAND (ptr, 1);
+
if (ostype == 0)
{
/* For raw memory functions like memcpy bail if the size
of the enclosing object cannot be determined. */
- access_ref tmpref;
tree ref = TREE_OPERAND (ptr, 0);
- if (!compute_objsize (ref, ostype, &tmpref, visited, rvals)
- || !tmpref.ref)
+ if (!compute_objsize (ref, ostype, pref, visited, rvals)
+ || !pref->ref)
return false;
+
+ /* Otherwise, use the size of the enclosing object and add
+ the offset of the member to the offset computed so far. */
+ tree offset = byte_position (field);
+ if (TREE_CODE (offset) != INTEGER_CST)
+ return false;
+ offset_int off = wi::to_offset (offset);
+ pref->offrng[0] += off;
+ pref->offrng[1] += off;
+ return true;
}
- tree field = TREE_OPERAND (ptr, 1);
/* Bail if the reference is to the pointer itself (as opposed
to what it points to). */
if (!addr && POINTER_TYPE_P (TREE_TYPE (field)))
@@ -4147,8 +4132,11 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
orng[0] *= sz;
orng[1] *= sz;
- if (TREE_CODE (eltype) == ARRAY_TYPE)
+ if (ostype && TREE_CODE (eltype) == ARRAY_TYPE)
{
+ /* Execpt for the permissive raw memory functions which
+ use the size of the whole object determined above,
+ use the size of the referenced array. */
pref->sizrng[0] = pref->offrng[0] + orng[0] + sz;
pref->sizrng[1] = pref->offrng[1] + orng[1] + sz;
}