ipa-cp: Punt for too large offsets [PR108605]
authorJakub Jelinek <jakub@redhat.com>
Sat, 11 Feb 2023 14:57:54 +0000 (15:57 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 11 Feb 2023 14:57:54 +0000 (15:57 +0100)
commit00a49047b504b27a8dd19d819c7bc48d54078767
tree5cdb32b02e61986b79e0f82adf513611cf09742d
parentd1bf1c9771de8bb7039352510c758569063638fd
ipa-cp: Punt for too large offsets [PR108605]

Seems most of IPA uses unsigned type for byte offsets
ipa-param-manipulation.h:  unsigned unit_offset;
ipa-param-manipulation.h:  unsigned unit_offset;
ipa-param-manipulation.h:  void register_replacement (tree base, unsigned unit_offset, tree replacement);
ipa-param-manipulation.h:  tree lookup_replacement (tree base, unsigned unit_offset);
ipa-param-manipulation.h:                                                   unsigned unit_offset);
ipa-prop.h:  unsigned unit_offset;
ipa-prop.h:  tree get_value (int index, unsigned unit_offset, bool by_ref) const;
ipa-prop.h:  tree get_value (int index, unsigned unit_offset) const;
ipa-prop.h:  const ipa_argagg_value *get_elt (int index, unsigned unit_offset) const;
ipa-cp.cc:ipa_argagg_value_list::get_elt (int index, unsigned unit_offset) const
ipa-cp.cc:  unsigned prev_unit_offset = 0;
ipa-cp.cc:ipa_argagg_value_list::get_value (int index, unsigned unit_offset) const
ipa-cp.cc:ipa_argagg_value_list::get_value (int index, unsigned unit_offset,
ipa-cp.cc:      unsigned other_offset = other.m_elts[i].unit_offset;
ipa-cp.cc:  unsigned prev_unit_offset = 0;
ipa-cp.cc:  unsigned prev_unit_offset = 0;
ipa-cp.cc:      unsigned this_offset = elts[i].unit_offset;
ipa-cp.cc:  unsigned prev_unit_offset = 0;
ipa-cp.cc:        unsigned unit_offset = aglat->offset / BITS_PER_UNIT;
ipa-cp.cc:  unsigned prev_unit_offset = 0;
ipa-param-manipulation.cc:  unsigned unit_offset;
ipa-param-manipulation.cc:isra_get_ref_base_and_offset (tree expr, tree *base_p, unsigned *unit_offset_p)
ipa-param-manipulation.cc:                                                unsigned unit_offset,
ipa-param-manipulation.cc:                                                unsigned unit_offset)
ipa-param-manipulation.cc:ipa_param_body_adjustments::lookup_replacement (tree base, unsigned unit_offset)
ipa-param-manipulation.cc:  unsigned unit_offset;
ipa-prop.cc:      unsigned unit_offset = bit_offset / BITS_PER_UNIT;
ipa-sra.cc:  unsigned unit_offset;
ipa-sra.cc:  unsigned unit_offset;
ipa-sra.cc:                          unsigned unit_offset, unsigned unit_size)
ipa-sra.cc:      unsigned offset = argacc->unit_offset + delta_offset;
so before converting a HOST_WIDE_INT bit offset to unsigned byte offset
we need to punt for too large offsets.  Some places do that, e.g.
isra_get_ref_base_and_offset has
  if (offset < 0 || (offset / BITS_PER_UNIT) > UINT_MAX)
    return false;
but ipa_agg_value_from_jfunc doesn't.

The following patch fixes that.

2023-02-11  Jakub Jelinek  <jakub@redhat.com>

PR ipa/108605
* ipa-cp.cc (ipa_agg_value_from_jfunc): Return NULL_TREE also if
item->offset bit position is too large to be representable as
unsigned int byte position.

* c-c++-common/pr108605.c: New test.
gcc/ipa-cp.cc
gcc/testsuite/c-c++-common/pr108605.c [new file with mode: 0644]