https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80121
--- Comment #4 from janus at gcc dot gnu.org --- Producing a dump via -fdump-tree-original shows what's going on in the case of comment #3, namely: 'e' is being deallocated before being passed to 's1': if ((struct t1[0:] * restrict) e.data != 0B) { __builtin_free ((void *) e.data); (struct t1[0:] * restrict) e.data = 0B; } s1 (&e); That is correct so far. However, what is missing is the deallocation of e's components. Those are only auto-deallocated at the end of the subroutine 'leak'.