https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128094
Bug ID: 128094
Summary: __builtin_dynamic_object_size returns 0 for
container_of through a char *
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: lightofmysoul at gmail dot com
Target Milestone: ---
Created attachment 65927
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65927&action=edit
testcase
With _FORTIFY_SOURCE=3, a valid strcpy into a struct member aborts if the
struct pointer was recovered container_of-style from a char *.
Testcase (attached as repro.c):
struct s {
char buf[8];
int x;
};
struct s a[2];
char *x = (char *)&a[argc].x;
char *buf = ((struct s *)(x - offsetof(struct s, x)))->buf;
strcpy(buf, "abc");
$ gcc -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 repro.c -o repro
/usr/include/bits/string_fortified.h:93:10: warning: ‘__builtin___memcpy_chk’
writing 4 bytes into a region of size 0 overflows the destination
[-Wstringop-overflow=]
$ ./repro
__builtin_object_size: 8, __builtin_dynamic_object_size: 0
*** buffer overflow detected ***: terminated
Aborted
__builtin_dynamic_object_size(buf, 1) should be 8, like
__builtin_object_size(buf, 1).
If x is an int * instead of a char *, it works. If the char * comes from
a ?: instead (repro2.c), even __builtin_object_size returns 0, so
_FORTIFY_SOURCE=2 aborts too.
gcc 16.2.1 20260926 (Gentoo), x86_64. Also happens on the current gcc-16
branch. Maybe related: PR 120780, PR 127875.
-----
I hit this while writing my own container_of macro with tests. I don't
really understand how it works inside GCC: an LLM analyzed it and pointed
at addr_object_size() in tree-object-size.cc. It also wrote a patch that
fixes both testcases, but it seems I can't attach it due to the GCC AI
policy?