aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-warn-restrict.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-06-10 12:00:08 -0600
committerMartin Sebor <msebor@redhat.com>2020-06-10 12:02:12 -0600
commita2c2cee92e5defff9bf23d3b1184ee96e57e5fdd (patch)
treeaba4fb6e58da7b6f6e30f7e67e716a20a1a8a5ff /gcc/gimple-ssa-warn-restrict.c
parent3a391adf7a38780f8d01dbac08a2a143fc80b469 (diff)
downloadgcc-a2c2cee92e5defff9bf23d3b1184ee96e57e5fdd.zip
gcc-a2c2cee92e5defff9bf23d3b1184ee96e57e5fdd.tar.gz
gcc-a2c2cee92e5defff9bf23d3b1184ee96e57e5fdd.tar.bz2
PR middle-end/95353 - spurious -Wstringop-overflow writing to a trailing array plus offset
Also resolves: PR middle-end/92939 - missing -Wstringop-overflow on negative index from the end of array gcc/ChangeLog: PR middle-end/95353 PR middle-end/92939 * builtins.c (inform_access): New function. (check_access): Call it. Add argument. (addr_decl_size): Remove. (get_range): New function. (compute_objsize): New overload. Only use compute_builtin_object_size with raw memory function. (check_memop_access): Pass new argument to compute_objsize and check_access. (expand_builtin_memchr, expand_builtin_strcat): Same. (expand_builtin_strcpy, expand_builtin_stpcpy_1): Same. (expand_builtin_stpncpy, check_strncat_sizes): Same. (expand_builtin_strncat, expand_builtin_strncpy): Same. (expand_builtin_memcmp): Same. * builtins.h (check_nul_terminated_array): Declare extern. (check_access): Add argument. (struct access_ref, struct access_data): New structs. * gimple-ssa-warn-restrict.c (clamp_offset): New helper. (builtin_access::overlap): Call it. * tree-object-size.c (decl_init_size): Declare extern. (addr_object_size): Correct offset computation. * tree-object-size.h (decl_init_size): Declare. * tree-ssa-strlen.c (handle_integral_assign): Remove a call to maybe_warn_overflow when assigning to an SSA_NAME. gcc/testsuite/ChangeLog: PR middle-end/95353 PR middle-end/92939 * c-c++-common/Wstringop-truncation.c: Remove an xfail. * gcc.dg/Warray-bounds-46.c: Remove a bogus warning. * gcc.dg/Wrestrict-9.c: Disable -Wstringop-overflow. * gcc.dg/Wstringop-overflow-12.c: Remove xfails. * gcc.dg/Wstringop-overflow-28.c: Same. * gcc.dg/builtin-stringop-chk-4.c: Same. * gcc.dg/builtin-stringop-chk-5.c: Same. * gcc.dg/builtin-stringop-chk-8.c: Same. * gcc.dg/strlenopt-74.c: Avoid buffer overflow. * gcc.dg/Wstringop-overflow-34.c: New test. * gcc.dg/Wstringop-overflow-35.c: New test. * gcc.dg/Wstringop-overflow-36.c: New test. * gcc.dg/Wstringop-overflow-37.c: New test. * gcc.dg/Wstringop-overflow-38.c: New test.
Diffstat (limited to 'gcc/gimple-ssa-warn-restrict.c')
-rw-r--r--gcc/gimple-ssa-warn-restrict.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 19d2ec0..512fc13 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1274,6 +1274,27 @@ builtin_access::strcpy_overlap ()
return generic_overlap ();
}
+/* For a BASE of array type, clamp REFOFF to at most [0, BASE_SIZE]
+ if known, or [0, MAXOBJSIZE] otherwise. */
+
+static void
+clamp_offset (tree base, offset_int refoff[2], offset_int maxobjsize)
+{
+ if (!base || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
+ return;
+
+ if (refoff[0] < 0 && refoff[1] >= 0)
+ refoff[0] = 0;
+
+ if (refoff[1] < refoff[0])
+ {
+ offset_int maxsize = maxobjsize;
+ if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (base)))
+ maxsize = wi::to_offset (size);
+
+ refoff[1] = wi::umin (refoff[1], maxsize);
+ }
+}
/* Return true if DSTREF and SRCREF describe accesses that either overlap
one another or that, in order not to overlap, would imply that the size
@@ -1312,35 +1333,12 @@ builtin_access::overlap ()
/* If the base object is an array adjust the bounds of the offset
to be non-negative and within the bounds of the array if possible. */
- if (dstref->base
- && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
- {
- if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
- acs.dstoff[0] = 0;
-
- if (acs.dstoff[1] < acs.dstoff[0])
- {
- if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
- acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
- else
- acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
- }
- }
+ clamp_offset (dstref->base, acs.dstoff, maxobjsize);
acs.srcoff[0] = srcref->offrange[0];
acs.srcoff[1] = srcref->offrange[1];
- if (srcref->base
- && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
- {
- if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
- acs.srcoff[0] = 0;
-
- if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
- acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
- else if (acs.srcoff[1] < acs.srcoff[0])
- acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
- }
+ clamp_offset (srcref->base, acs.srcoff, maxobjsize);
/* When the upper bound of the offset is less than the lower bound
the former is the result of a negative offset being represented