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

            Bug ID: 124665
           Summary: -Wstringop-overflow false positive when inlining
           Product: gcc
           Version: 14.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jiangxuezhi2 at huawei dot com
  Target Milestone: ---

I’m encountering a confusing -Wstringop-overflow warning that only appears when
a function gets inlined, but disappears with -fno-inline. This seems like a
static analyzer false positive after inlining.

Here’s what my code essentially does (simplified):

~~~c
static void test2(UINT32 startSn, UINT32 endSn, UINT8 *appHdr)
{
    CommonAppHdrStru *pdcpAppHdr = (CommonAppHdrStru*)appHdr;
    UINT8 *data = appHdr;

    pdcpAppHdr->firstOctetOfSequenceNum = 0;
    pdcpAppHdr->secondOctetOfSequenceNum = 0;
    pdcpAppHdr->npduNum = 0;
    pdcpAppHdr->nextExtensionHdrType = (UINT8)0x84;
    offset += sizeof(CommonAppHdrStru);

    rsvd = data + offset;
    *rsvd = 0;
    nextType = data + offset + sizeof(UINT8);
    *nextType = 0;
}


static void test1(...)
{
    RbdStru *sduRbd = 0L;
    sduRbd->offset = (UINT16)(192);
    sduRbd->length = (UINT16)(sizeof(CommonAppHdrStru));

    CommonDlSduStru *commHdr = (CommonDlSduStru*)(L2OS_GetRbdPayload(sduRbd));

    test2(startSn, endSn, (UINT8*)&commHdr->pdcpAppHdr);
}
~~~
The warning:

In function 'test2',
 warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
...: In function 'test1':
...:244:22: note: at offset [22, 34] into destination object 'pdcpAppHdr' of
size 4
...:244:22: note: at offset [22, 34] into destination object 'pdcpAppHdr' of
size 4
In function 'test2',
    inlined from 'test1' at ...
warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
...: In function 'test1':
...:244:22: note: at offset [23, 35] into destination object 'pdcpAppHdr' of
size 4
...:244:22: note: at offset [23, 35] into destination object 'pdcpAppHdr' of
size 4



When test2() receives a UINT8* buffer pointer that we temporarily cast to a
smaller CommonAppHdrStru* (size 4) for structured field access, but then
continue using the original UINT8* pointer for byte-level arithmetic at larger
offsets (22+). 

When inlining happens, GCC’s analyzer seems to incorrectly constrain the entire
buffer to the smaller 4-byte structure size from the cast, losing track of the
fact that we’re actually working with a much larger buffer from
L2OS_GetRbdPayload(sduRbd). 

I’m wondering if this is a known limitation in how GCC tracks pointer
provenance across type casts during inlining, and whether there are suggested
annotations or if this represents a gap in the compute_objsize logic that needs
improvement.
  • [Bug c/124665] New: -Wstringop... jiangxuezhi2 at huawei dot com via Gcc-bugs

Reply via email to