https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87313
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=91582 --- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> --- This limitation is also getting in the way of detecting out-of-bounds accesses by string functions to dynamically allocated arrays, including VLAs. With the patch for pr91582 I'm testing, GCC detects the invalid access in functions f0() and f3() below, but because of this limitation, it doesn't detect the same bug in functions f1() or f2() (when the loop is unrolled). That's because __builtin_alloca_with_align is neither declared with attribute malloc nor recognized as "special" like malloc in that the pointer it returns doesn't alias any other pointer in the program. $ cat c.c && gcc -O2 -S -Wall -Wextra c.c $ cat c.c && /build/gcc-91582/gcc/xgcc -B /build/gcc-91582/gcc -O2 -S -Wall -Wextra c.c void sink (void*); void f0 (unsigned n) { if (n > 4) n = 4; char a[n]; a[4] = 0; // warning (good) sink (a); } void f1 (unsigned n) { if (n > 4) n = 4; char a[n]; a[3] = 0; a[4] = 0; // missing warning sink (a); } void f2 (unsigned n) { if (n > 4) n = 4; char a[n]; int i = 0; do { a[i] = i; // missing warning when loop is unrolled } while (i++ != 4); sink (a); } void f3 (unsigned n) { if (n > 4) n = 4; char *p = (char*)__builtin_malloc (n); int i = 0; do { p[i] = i; // warning (good) } while (i++ != 4); sink (p); } c.c: In function ‘f0’: c.c:9:8: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 9 | a[4] = 0; // warning (good) | ~~~~~^~~ c.c:8:8: note: at offset 4 to an object with size at most 4 declared here 8 | char a[n]; | ^ c.c: In function ‘f3’: c.c:45:10: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 45 | p[i] = i; // warning (good) | ~~~~~^~~ c.c:42:20: note: at offset 4 to an object with size at most 4 allocated by ‘__builtin_malloc’ here 42 | char *p = (char*)__builtin_malloc (n); | ^~~~~~~~~~~~~~~~~~~~