On 11/6/19 11:00 AM, Martin Sebor wrote: > The -Wstringop-overflow warnings for single-byte and multi-byte > stores mention the amount of data being stored and the amount of > space remaining in the destination, such as: > > warning: writing 4 bytes into a region of size 0 [-Wstringop-overflow=] > 123 | *p = 0; > | ~~~^~~ > note: destination object declared here > 45 | char b[N]; > | ^ > > A warning like this can take some time to analyze. First, the size > of the destination isn't mentioned and may not be easy to tell from > the sources. In the note above, when N's value is the result of > some non-trivial computation, chasing it down may be a small project > in and of itself. Second, it's also not clear why the region size > is zero. It could be because the offset is exactly N, or because > it's negative, or because it's in some range greater than N. > > Mentioning both the size of the destination object and the offset > makes the existing messages clearer, are will become essential when > GCC starts diagnosing overflow into allocated buffers (as my > follow-on patch does). > > The attached patch enhances -Wstringop-overflow to do this by > letting compute_objsize return the offset to its caller, doing > something similar in get_stridx, and adding a new function to > the strlen pass to issue this enhanced warning (eventually, I'd > like the function to replace the -Wstringop-overflow handler in > builtins.c). With the change, the note above might read something > like: > > note: at offset 11 to object ‘b’ with size 8 declared here > 45 | char b[N]; > | ^ > > Tested on x86_64-linux. > > Martin > > gcc-store-offset.diff > > gcc/ChangeLog: > > * builtins.c (compute_objsize): Add an argument and set it to offset > into destination. > * builtins.h (compute_objsize): Add an argument. > * tree-object-size.c (addr_object_size): Add an argument and set it > to offset into destination. > (compute_builtin_object_size): Same. > * tree-object-size.h (compute_builtin_object_size): Add an argument. > * tree-ssa-strlen.c (get_addr_stridx): Add an argument and set it > to offset into destination. > (maybe_warn_overflow): New function. > (handle_store): Call maybe_warn_overflow to issue warnings. > > gcc/testsuite/ChangeLog: > > * c-c++-common/Wstringop-overflow-2.c: Adjust text of expected messages. > * g++.dg/warn/Wstringop-overflow-3.C: Same. > * gcc.dg/Wstringop-overflow-17.c: Same. >
> Index: gcc/tree-ssa-strlen.c > =================================================================== > --- gcc/tree-ssa-strlen.c (revision 277886) > +++ gcc/tree-ssa-strlen.c (working copy) > @@ -189,6 +189,52 @@ struct laststmt_struct > static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, > tree); > static void handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator > *); > > +/* Sets MINMAX to either the constant value or the range VAL is in > + and returns true on success. */ > + > +static bool > +get_range (tree val, wide_int minmax[2], const vr_values *rvals = NULL) > +{ > + if (tree_fits_uhwi_p (val)) > + { > + minmax[0] = minmax[1] = wi::to_wide (val); > + return true; > + } > + > + if (TREE_CODE (val) != SSA_NAME) > + return false; > + > + if (rvals) > + { > + gimple *def = SSA_NAME_DEF_STMT (val); > + if (gimple_assign_single_p (def) > + && gimple_assign_rhs_code (def) == INTEGER_CST) > + { > + /* get_value_range returns [0, N] for constant assignments. */ > + val = gimple_assign_rhs1 (def); > + minmax[0] = minmax[1] = wi::to_wide (val); > + return true; > + } Umm, something seems really off with this hunk. If the SSA_NAME is set via a simple constant assignment, then the range ought to be a singleton ie [CONST,CONST]. Is there are particular test were this is not true? The only way offhand I could see this happening is if originally the RHS wasn't a constant, but due to optimizations it either simplified into a constant or a constant was propagated into an SSA_NAME appearing on the RHS. This would have to happen between the last range analysis and the point where you're making this query. > + > + // FIXME: handle anti-ranges? > + return false; Please don't if we can avoid them. anti-ranges are on the chopping block, so I'd prefer not to add cases where we're trying to handle them if we can reasonably avoid it. No objections elsewhere. So I think we just need to figure out what's going on with the ranges when you've got an INTEGER_CST on the RHS of an assignment. jeff