https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105726
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > The following fixes the bogus diagnostic: > > diff --git a/gcc/gimple-ssa-warn-restrict.cc > b/gcc/gimple-ssa-warn-restrict.cc > index b678e806da3..25c63f99c61 100644 > --- a/gcc/gimple-ssa-warn-restrict.cc > +++ b/gcc/gimple-ssa-warn-restrict.cc > @@ -539,13 +559,6 @@ builtin_memref::set_base_and_offset (tree expr) > offset_int off = tree_to_shwi (memrefoff); > refoff += off; > } > - > - if (!integer_zerop (memrefoff)) > - /* A non-zero offset into an array of struct with flexible array > - members implies that the array is empty because there is no > - way to initialize such a member when it belongs to an array. > - This must be some sort of a bug. */ > - refsize = 0; > } > > if (TREE_CODE (ref) == COMPONENT_REF) It for example regresses gcc.dg/Warray-bounds-46.c which essentially does struct X { char pad[4]; char ax[]; }; void foo (struct X *p, char *a) { __builtin_strcpy (p[1].ax, a); } and the intent was to detect that p[1] implies a zero-size 'ax'. That's going to be interesting to distinguish from our case here with just the MEM_REF - possibly the easiest heuristic is to trigger this only for incomplete TREE_TYPE of the MEM_REF at least. That will still trigger in too many cases, requiring the MEM_REF offset to be a multiple of the size of the struct will trigger in not enough cases (if there's also an embedded offset into the array). But maybe it's a good compromise: diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc index b678e806da3..734cdd7f5b4 100644 --- a/gcc/gimple-ssa-warn-restrict.cc +++ b/gcc/gimple-ssa-warn-restrict.cc @@ -525,7 +525,6 @@ builtin_memref::set_base_and_offset (tree expr) { tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1)); extend_offset_range (memrefoff); - base = TREE_OPERAND (base, 0); if (refoff != HOST_WIDE_INT_MIN && TREE_CODE (expr) == COMPONENT_REF) @@ -538,14 +537,19 @@ builtin_memref::set_base_and_offset (tree expr) REFOFF is set to s[1].b - (char*)s. */ offset_int off = tree_to_shwi (memrefoff); refoff += off; - } - - if (!integer_zerop (memrefoff)) - /* A non-zero offset into an array of struct with flexible array - members implies that the array is empty because there is no - way to initialize such a member when it belongs to an array. - This must be some sort of a bug. */ - refsize = 0; + + if (!integer_zerop (memrefoff) + && !COMPLETE_TYPE_P (TREE_TYPE (expr)) + && multiple_of_p (sizetype, memrefoff, + TYPE_SIZE_UNIT (TREE_TYPE (base)), true)) + /* A non-zero offset into an array of struct with flexible array + members implies that the array is empty because there is no + way to initialize such a member when it belongs to an array. + This must be some sort of a bug. */ + refsize = 0; + } + + base = TREE_OPERAND (base, 0); } if (TREE_CODE (ref) == COMPONENT_REF)