Bug 98553 - missing warning on strncmp reading past the end of a zero size member array
Summary: missing warning on strncmp reading past the end of a zero size member array
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overread
  Show dependency treegraph
 
Reported: 2021-01-05 22:53 UTC by Martin Sebor
Modified: 2021-01-05 22:53 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2021-01-05 22:53:32 UTC
GCC diagnoses the out-of-bounds reads by strcmp in fx and f0 but fails to diagnose the corresponding out-of-bounds reads by strncmp in gx and g0.  In all four functions the size of the character array is zero and so each call to the string function starts reading past its end, and so past the end of the enclosing object.

$ cat b.c && gcc -O2 -S -Wall -Wextra b.c
extern int strcmp (const char*, const char*);

void init (void*);

int fx (void)
{
  struct { char n, a[]; } a;
  init (&a);
  return 0 == strcmp (a.a, "123");   // -Wstringop-overread (good)
}

int f0 (void)
{
  struct { char n, a[0]; } a;
  init (&a);
  return 0 == strcmp (a.a, "123");   // -Wstringop-overread (good)
}


extern int strncmp (const char*, const char*, __SIZE_TYPE__);

int gx (void)
{
  struct { char n, a[]; } a;
  init (&a);
  return 0 == strncmp (a.a, "123", 3);   // missing -Wstringop-overread
}

int g0 (void)
{
  struct { char n, a[0]; } a;
  init (&a);
  return 0 == strncmp (a.a, "123", 3);   // missing -Wstringop-overread
}
b.c: In function ‘fx’:
b.c:9:15: warning: ‘strcmp’ reading 1 or more bytes from a region of size 0 [-Wstringop-overread]
    9 |   return 0 == strcmp (a.a, "123");   // -Wstringop-overread (good)
      |               ^~~~~~~~~~~~~~~~~~~
b.c:7:20: note: source object ‘a’ of size 0
    7 |   struct { char n, a[]; } a;
      |                    ^
b.c: In function ‘f0’:
b.c:16:15: warning: ‘strcmp’ reading 1 or more bytes from a region of size 0 [-Wstringop-overread]
   16 |   return 0 == strcmp (a.a, "123");   // -Wstringop-overread (good)
      |               ^~~~~~~~~~~~~~~~~~~
b.c:14:20: note: source object ‘a’ of size 0
   14 |   struct { char n, a[0]; } a;
      |                    ^