https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100717
Bug ID: 100717 Summary: missing warning for a call to a function with attribute access inlined into caller Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- GCC issues warnings for (likely) out of bounds accesses by calls to functions declared with attribute access. An example is the call to f0() in f1() below. But no warning is issued when the called function is inlined, as happens with g0() in g1(). This is because the attribute on the called function disappears once it's inlined. This problem could be solved either by (also) issuing the warning early, just before inlining, for the subset of calls with constant arguments, or by preserving the call statements in some data structure even after they have been inlined and analyzing them much later, after constant and range propagation, if they're not removed by dead code elimination. $ cat a.c && gcc -O2 -S -Wall a.c __attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) __attribute__ ((noinline)) void f0 (int *a, const int *b, unsigned n) { for (unsigned i = 0; i != n; ++i) a[i] += b[i]; } void f1 (int a[4]) { f0 (a, (int[]){ 3, 3, 3 }, 4); // warning (good) } __attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void g0 (int *a, const int *b, unsigned n) { for (unsigned i = 0; i != n; ++i) a[i] += b[i]; } void g1 (int a[4]) { g0 (a, (int[]){ 3, 3, 3 }, 4); // missing warning } a.c: In function ‘f1’: a.c:11:3: warning: ‘f0’ reading 16 bytes from a region of size 12 [-Wstringop-overread] 11 | f0 (a, (int[]){ 3, 3, 3 }, 4); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.c:11:17: note: source object ‘<Uabd0>’ of size 12 11 | f0 (a, (int[]){ 3, 3, 3 }, 4); // warning (good) | ^ a.c:3:6: note: in a call to function ‘f0’ declared with attribute ‘access (read_only, 2, 3)’ 3 | void f0 (int *a, const int *b, unsigned n) | ^~