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.

Reply via email to