https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105726
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |msebor at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Oh, my - this is mightly complicated code. We get to void builtin_memref::set_base_and_offset (tree expr) { ... if (TREE_CODE (base) == MEM_REF) { 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) { /* Bump up the offset of the referenced subobject to reflect the offset to the enclosing object. For example, so that in struct S { char a, b[3]; } s[2]; strcpy (s[1].b, "1234"); REFOFF is set to s[1].b - (char*)s. */ offset_int off = tree_to_shwi (memrefoff); refoff += off; } which looks somewhat suspicious and then tree builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const { ... /* When the referenced subobject is known, the end offset must be within its bounds. Otherwise there is nothing to do. */ if (strict && !decl_p && ref && refsize >= 0 && TREE_CODE (ref) == COMPONENT_REF) { /* If REFOFF is negative, SIZE will become negative here. */ size = refoff + refsize; obj = ref; triggers with ref being a COMPONENT_REF to the array, refoff being 4 (from the MEM_REF) and refsize == 0. The idea is probably that the '4' is for the pointer adjustment (base is &aMessage here), but then the object shouldn't be 'ref'? But I'm confused by all the complexity and the abstraction and I'm sure starting to deleting code that confuses me will cause all sorts of regressions in the diagnostic parts of the testsuite. Martin - can you have a look here and maybe give directions? In particular how 'refoff' and 'offrange' depend (or if they stand on its own). I think that &ref - &base == refoff? So for &MEM[(const struct array *)aMessage_1(D) + 4B]._M_elems having ref = MEM[(const struct array *)aMessage_1(D) + 4B]._M_elems, base = aMessage_1(D), refoff = 4 and offrange[] = {4, 4} looks OK. But then I'm confused as to why the diagnostic triggers. Maybe that's because refsize == 0 which is a special case for "unknown"? That's because ref analysis does 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; on the MEM_REF path. But I don't understand how the comment applies here - there is no flexibel array member involved, in particular the MEM_REF doesn't offset an array it offsets struct X. So I'm inclined to simply kill the above ...?