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?

Reply via email to