https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128094
--- Comment #3 from lightofmysoul at gmail dot com --- Created attachment 65932 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65932&action=edit container_of: pointer arithmetic vs uintptr_t Thanks for the explanation! I understand the strict reading, but GCC seems to support this idiom on purpose: PR 120780 added it, and its test (builtin-dynamic-object-size-pr120780.c, test3) does the same through a char * and expects the correct sizes. The only difference in my case is that the member is an int, not a char array. GCC also returns 8 for __builtin_object_size(buf, 1), 12 for __builtin_dynamic_object_size(buf, 0), and 8 when x is an int *. Only __builtin_dynamic_object_size(buf, 1) through a char * or void * gives 0. I moved my container_of from uintptr_t to pointer arithmetic because with uintptr_t the compilers lose track of the object. The attached uintptr.c shows it for GCC (gcc -O2 -S uintptr.c, with and without -DUINTPTR): with uintptr_t the out-of-bounds write in oob() is no longer warned about, and two() has to reload sa->buf[0]. And additionally with clang it is even worse: its fortify and UBSan miss real overflows, and more asm is generated...
