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 ...?

Reply via email to