https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120929
--- Comment #12 from Siddhesh Poyarekar <siddhesh at gcc dot gnu.org> --- This is interesting here's the IR dump right after objsz: struct magic_map * apprentice_load () { unsigned int i; char b[1024]; struct magic_ * ptr; struct magic_map * map2; char buf[128]; struct magic_ * * _1; void * _9; long unsigned int _11; <bb 2> [local count: 1073741824]: map2_4 = __builtin_malloc (8); pin_pointer (&buf); _1 = &map2_4->magic; _9 = __builtin_malloc (9); *_1 = _9; goto <bb 4>; [100.00%] <bb 3> [local count: 1073741824]: b = ""; ptr_10 = *_1; _11 = 8; __builtin___memcpy_chk (ptr_10, &b, 9, _11); b ={v} {CLOBBER(eos)}; i_13 = i_12 + 1; <bb 4> [local count: 2147483648]: # i_12 = PHI <0(2), i_13(3)> if (i_12 == 0) goto <bb 3>; [50.00%] else goto <bb 5>; [50.00%] <bb 5> [local count: 1073741824]: pin_pointer (map2_4); buf ={v} {CLOBBER(eos)}; return; } The key bit is: map2_4 = __builtin_malloc (8); pin_pointer (&buf); _1 = &map2_4->magic; _9 = __builtin_malloc (9); *_1 = _9; goto <bb 4>; [100.00%] <bb 3> [local count: 1073741824]: b = ""; ptr_10 = *_1; _11 = 8; __builtin___memcpy_chk (ptr_10, &b, 9, _11); where *_1 gets updated to _9, but when one follows the *_1 through ptr_10, it doesn't end up with _9, the def statement is: _1 = &map2_4->magic; which leads to the incorrect value for the object size. This is because the pass doesn't know that a MEM_REF could be the LHS (for the zero byte offset case like it is here) for an assignment, i.e. this: *_1 = _9;