On 10/14/19 6:23 PM, Martin Sebor wrote:
> When a subsequent element or member of a local aggregate containing
> a prior character array is initialized the strlen pass discards
> the length it computed for the prior element/member. E.g., here:
>
> struct { char a[4], b[4]; } s = { "1", "12" };
>
> even though strlen (s.b) is folded to 2, strlen (s.a) is not. (Ditto
> for other stores even to members of other types.) This causes hundreds
> (over 700 in GCC) to thousands (nearly 3,000 in Binutils/GDB and some
> 36,000 in the kernel) of instances of previously computed string lengths
> to end up discarded and so besides emitting less than optimal code also
> defeats buffer overflow detection in such cases.
>
> Attached is a resubmission of a previously approved patch that I never
> committed (the original had a bug that was noted during review that
> I subsequently fixed but I didn't remember to post the corrected patch).
> Tested on x86_64-linux.
>
> Martin
>
> gcc-83821.diff
>
> PR tree-optimization/83821 - local aggregate initialization defeats strlen
> optimization
>
> gcc/ChangeLog:
>
> PR tree-optimization/83821
> * tree-ssa-strlen.c (maybe_invalidate): Add argument. Consider
> the length of a string when available.
> (handle_builtin_memset) Add argument.
> (handle_store, strlen_check_and_optimize_call): Same.
> (check_and_optimize_stmt): Same. Pass it to callees.
>
> gcc/testsuite/ChangeLog:
>
> PR tree-optimization/83821
> * c-c++-common/Warray-bounds-4.c: Remove XFAIL.
> * gcc.dg/strlenopt-80.c: New test.
> * gcc.dg/strlenopt-81.c: Same.
> * gcc.dg/strlenopt-82.c: Same.
> * gcc.dg/strlenopt-83.c: Same.
> * gcc.dg/strlenopt-84.c: Same.
> * gcc.dg/tree-ssa/calloc-4.c: Same.
> * gcc.dg/tree-ssa/calloc-5.c: Same.
OK.
Jeff