https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120780
--- Comment #9 from Siddhesh Poyarekar <siddhesh at gcc dot gnu.org> --- I haven't properly reduced this yet, but the key difference appears to be this: - ifmsh_2 = &MEM[(struct ieee80211_sub_if_data *)dev_1(D) + 2624B].u.mesh; - _6 = &MEM[(struct ieee80211_sub_if_data *)ifmsh_2 + -2872B].vif.bss_conf.mcast_rate; + _1 = &dev_3(D)->priv; + _2 = &dev_3(D)->priv_len; + _20 = MEM <u32> [(void *)_2]; + _8 = (sizetype) _20; + sdata_5 = .ACCESS_WITH_SIZE (_1, _2, 1, 0, -1, 0B); + _21 = MAX_EXPR <_8, 2872>; + _19 = _21 + 18446744073709548744; + ifmsh_6 = &sdata_5->u.mesh; + _10 = &MEM[(struct ieee80211_sub_if_data *)ifmsh_6 + -2872B].vif.bss_conf.mcast_rate; + _11 = 0; objsz bails out when trying to compute the size for dev on gcc14 (since it doesn't have __counted_by__ support and hence can't say anything for the struct with FAM) whereas on gcc15 and later, it gets the size for ifmsh_6 and then when it encounters a constant negative offset (the jump to the parent container of ifmsh), it doesn't accept the negative offset in size_for_offset: /* Negative or too large offset even after adjustment, cannot be within bounds of an object. The exception here is when the base object size has been overestimated (e.g. through PHI nodes or a COND_EXPR) and the adjusted offset remains negative. If the caller wants to be permissive, return the base size. */ if (compare_tree_int (offset, offset_limit) > 0) { if (strict) return size_zero_node; else return sz; } This affects only subobject size because in the whole size case, the offset expression is not constant (something like (MAX_EXPR <_8, _18> - _18) + 18446744073709548744) because of which it does not shortcut to failure at compile time.