From a2c2cee92e5defff9bf23d3b1184ee96e57e5fdd Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 10 Jun 2020 12:00:08 -0600 Subject: 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. --- gcc/tree-object-size.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'gcc/tree-object-size.c') diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 8855065..bc55b27 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -172,7 +172,7 @@ compute_object_offset (const_tree expr, const_tree var) is true, else null. An object's initializer affects the object's size if it's a struct type with a flexible array member. */ -static tree +tree decl_init_size (tree decl, bool min) { tree size = DECL_SIZE_UNIT (decl); @@ -259,6 +259,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, offset_int mem_offset; if (mem_ref_offset (pt_var).is_constant (&mem_offset)) { + if (*poff) + *poff = wide_int_to_tree (ptrdiff_type_node, + mem_offset + wi::to_offset (*poff)); + else + *poff = wide_int_to_tree (ptrdiff_type_node, mem_offset); offset_int dsz = wi::sub (sz, mem_offset); if (wi::neg_p (dsz)) sz = 0; @@ -413,12 +418,12 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var); if (bytes != error_mark_node) { + *poff = bytes; if (TREE_CODE (bytes) == INTEGER_CST && tree_int_cst_lt (var_size, bytes)) bytes = size_zero_node; else bytes = size_binop (MINUS_EXPR, var_size, bytes); - *poff = bytes; } if (var != pt_var && pt_var_size @@ -441,7 +446,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, else if (!pt_var_size) return false; else - bytes = pt_var_size; + { + bytes = pt_var_size; + if (!*poff) + *poff = size_zero_node; + } if (tree_fits_uhwi_p (bytes)) { -- cgit v1.1