public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-5818] ipa-cp: Punt for too large offsets [PR108605]
@ 2023-02-11 14:58 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-02-11 14:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:00a49047b504b27a8dd19d819c7bc48d54078767

commit r13-5818-g00a49047b504b27a8dd19d819c7bc48d54078767
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Feb 11 15:57:54 2023 +0100

    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.

Diff:
---
 gcc/ipa-cp.cc                         |  4 +++-
 gcc/testsuite/c-c++-common/pr108605.c | 24 ++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 826bbc6222b..4b8dedc0c51 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1982,7 +1982,9 @@ ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
   tree value = NULL_TREE;
   int src_idx;
 
-  if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
+  if (item->offset < 0
+      || item->jftype == IPA_JF_UNKNOWN
+      || item->offset >= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT)
     return NULL_TREE;
 
   if (item->jftype == IPA_JF_CONST)
diff --git a/gcc/testsuite/c-c++-common/pr108605.c b/gcc/testsuite/c-c++-common/pr108605.c
new file mode 100644
index 00000000000..418b37d7019
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr108605.c
@@ -0,0 +1,24 @@
+/* PR ipa/108605 */
+/* { dg-do compile { target { lp64 || llp64 } } } */
+/* { dg-options "-O2" } */
+
+struct S {
+  char a, b, c;
+  int d[__INT_MAX__], e;
+};
+
+void
+foo (struct S *s)
+{
+  if (s->b && s->c != 0)
+    __builtin_abort ();
+}
+
+void
+bar (void)
+{
+  struct S s[2];
+  s[0].a = 0;
+  s[0].e = 0;
+  foo (s);
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-11 14:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-11 14:58 [gcc r13-5818] ipa-cp: Punt for too large offsets [PR108605] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).