https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103292

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID
           Keywords|                            |diagnostic
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=102151
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning is intended.  The program allocates an object of a size that's
smaller than the size of the type used to access it:

       pPicture->pSourcePict = (union _SourcePict*) malloc(sizeof(struct
_PictSolidFill));
        pPicture->pSourcePict->type = 0;

It's not valid to access an object of one type using an lvalue of another.  In
simple cases GCC diagnoses violations of this requirement by -Wstrict-aliasing.
 -Warray-bounds doesn't detect aliasing violations but it does detect a subset
of the problem that's apparent when the size of the lvalue's type is greater
than the size of the object.  The object must be big enough for the whole
lvalue, even if the accessed member is within the bounds of the smaller object.

The following is a smaller test case that should make the issue clearer.  See
also pr102151 for a similar report.

$ cat a.c && gcc -O2 -S -Wall a.c
struct A { char a[1]; };
struct B { char a[2]; };
union U { struct A a; struct B b; };

void* f (void)
{
  union U *p = __builtin_malloc (sizeof (struct A));
  p->a.a[0] = 0;
  return p;
}
a.c: In function ‘f’:
a.c:8:4: warning: array subscript ‘union U[0]’ is partly outside array bounds
of ‘unsigned char[1]’ [-Warray-bounds]
    8 |   p->a.a[0] = 0;
      |    ^~
a.c:7:16: note: object of size 1 allocated by ‘__builtin_malloc’
    7 |   union U *p = __builtin_malloc (sizeof (struct A));
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to