https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96508
Bug ID: 96508 Summary: missing warning for invalid calls to builtins from inline functions defined in system headers Product: gcc Version: 11.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: --- Prompted by the discussion at https://gcc.gnu.org/pipermail/gcc-patches/2020-August/551526.html, the test case below shows that warnings aren't issued for invalid calls to built-in functions like memcpy called from inline functions defined in system headers unless those inline functions are also declared artificial. Since the artificial attribute is used only rarely (there are only two instances of it in all of libstdc++), this limitation defeats most out-of-bounds checking in such wrappers. $ gcc -O2 -S -Wall -Wextra x.c #ifndef SYSTEM_HEADER_H #define SYSTEM_HEADER_H #pragma GCC system_header __attribute__ ((access (write_only, 1, 3))) void sys_func (void*, const void*, int); __attribute__ ((access (write_only, 1, 3), artificial)) static inline void sys_func_artificial_inline (void *d, const void *s, int n) { __builtin_memcpy (d, s, n); } __attribute__ ((access (write_only, 1, 3))) static inline void sys_func_inline (void *d, const void *s, int n) { __builtin_memcpy (d, s, n); } #endif // SYSTEM_HEADER_H #include "system-header.h" __attribute__ ((access (write_only, 1, 3))) static inline void func_inline (void *d, const void *s, int n) { sys_func (d, s, n); } void* f1 (const void *s) { void *d = __builtin_malloc (3); sys_func (d, s, 5); // warning (good) return d; } void* f2 (const void *s) { void *d = __builtin_malloc (3); sys_func_artificial_inline (d, s, 6); // warning (good) return d; } void* f3 (const void *s) { void *d = __builtin_malloc (3); sys_func_inline (d, s, 7); // missing warning! return d; } void* f4 (const void *s) { void *d = __builtin_malloc (3); func_inline (d, s, 8); // warning (good) return d; } x.c: In function ‘f1’: x.c:12:3: warning: ‘sys_func’ writing 5 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=] 12 | sys_func (d, s, 5); // warning (good) | ^~~~~~~~~~~~~~~~~~ In file included from x.c:1: system-header.h:7:1: note: in a call to function ‘sys_func’ declared with attribute ‘write_only (1, 3)’ 7 | sys_func (void*, const void*, int); | ^~~~~~~~ In function ‘sys_func_artificial_inline’, inlined from ‘f2’ at x.c:19:3: system-header.h:12:3: warning: ‘__builtin_memcpy’ writing 6 bytes into a region of size 3 [-Wstringop-overflow=] 12 | __builtin_memcpy (d, s, n); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ x.c: In function ‘f2’: x.c:18:13: note: at offset 0 to an object with size 3 allocated by ‘__builtin_malloc’ here 18 | void *d = __builtin_malloc (3); | ^~~~~~~~~~~~~~~~~~~~ In function ‘func_inline’, inlined from ‘f4’ at x.c:33:3: x.c:6:3: warning: ‘sys_func’ writing 8 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=] 6 | sys_func (d, s, n); | ^~~~~~~~~~~~~~~~~~ In file included from x.c:1: x.c: In function ‘f4’: system-header.h:7:1: note: in a call to function ‘sys_func’ declared with attribute ‘write_only (1, 3)’ 7 | sys_func (void*, const void*, int); | ^~~~~~~~