In LP64, only the buffer overflow in f() below is diagnosed. The one in g() is not because n is determined to be in the anti-range ~[4, 18446744071562067967], i.e., the size of the object is considered to be between [0, 4] and [INT_MAX, SIZE_MAX]. (In ILP32 both calls are diagnosed). The warning should try to determine the type of the argument to malloc() and if it's signed, assume it's not negative. $ cat a.c && gcc -D_FORTIFY_SOURCE=2 -O2 -S -Wall a.c #include <stdlib.h> #include <string.h> void* f (unsigned n) { if (3 < n) n = 3; void *p = malloc (n); strcpy (p, "12345"); // buffer overflow detected return p; } void* g (int n) { if (3 < n) n = 3; void *p = malloc (n); strcpy (p, "12345"); // buffer overflow not detected return p; } In file included from /usr/include/string.h:494, from a.c:2: In function ‘strcpy’, inlined from ‘f’ at a.c:10:3: /usr/include/bits/string_fortified.h:90:10: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=] 90 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.c: In function ‘f’: a.c:9:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here 9 | void *p = malloc (n); | ^~~~~~~~~~
Testing a fix.
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2020-August/552903.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:c0b09c1296d5334d1d264ba4d39ca932f9572330 commit r11-4441-gc0b09c1296d5334d1d264ba4d39ca932f9572330 Author: Martin Sebor <msebor@redhat.com> Date: Tue Oct 27 08:31:53 2020 -0600 Add tests for PR92942 - missing -Wstringop-overflow for allocations with a negative lower bound size. gcc/testsuite/ChangeLog: PR middle-end/92942 * gcc.dg/Wstringop-overflow-56.c: New test. * gcc.dg/Wstringop-overflow-57.c: Same.
The patch referenced in comment #2 was never reviewed but the bug was resolved by the improvements to compute_objsize() committed as part of the fix for pr97342. GCC 11 detects both buffer overflows: $ gcc -O2 -S -Wall pr92942.c pr92942.c: In function ‘f’: pr92942.c:10:3: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=] 10 | strcpy (p, "12345"); // buffer overflow detected | ^~~~~~~~~~~~~~~~~~~ pr92942.c:9:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here 9 | void *p = malloc (n); | ^~~~~~~~~~ pr92942.c: In function ‘g’: pr92942.c:20:3: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size between 0 and 3 [-Wstringop-overflow=] 20 | strcpy (p, "12345"); // buffer overflow not detected | ^~~~~~~~~~~~~~~~~~~ pr92942.c:19:13: note: at offset 0 to an object with size at most 3 allocated by ‘malloc’ here 19 | void *p = malloc (n); | ^~~~~~~~~~