On October 2, 2017 3:54:18 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >On the following testcase we get a ref where >ref->offset fits into shwi, so does ref->size, but ref->offset + >ref->size >doesn't. I see many spots where we just assume that ref->offset + >ref->size >is meaningful, so rather than adding overflow checking in all those >spots, >this patch instead let us punt in those cases. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. >2017-10-02 Jakub Jelinek <ja...@redhat.com> > > * tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1 > if *poffset + *pmax_size overflows in HOST_WIDE_INT. > Set *poffset to 0 and *psize and *pmax_size to -1 if > *poffset + *psize overflows in HOST_WIDE_INT. > > * gcc.dg/pr82389.c: New test. > >--- gcc/tree-dfa.c.jj 2017-05-22 10:50:07.000000000 +0200 >+++ gcc/tree-dfa.c 2017-10-02 12:29:01.103394300 +0200 >@@ -654,7 +654,22 @@ get_ref_base_and_extent (tree exp, HOST_ > if (!wi::fits_shwi_p (maxsize) || wi::neg_p (maxsize)) > *pmax_size = -1; > else >- *pmax_size = maxsize.to_shwi (); >+ { >+ *pmax_size = maxsize.to_shwi (); >+ if (*poffset > HOST_WIDE_INT_MAX - *pmax_size) >+ *pmax_size = -1; >+ } >+ >+ /* Punt if *POFFSET + *PSIZE overflows in HOST_WIDE_INT, the callers >don't >+ check for such overflows individually and assume it works. */ >+ if (*psize != -1 && *poffset > HOST_WIDE_INT_MAX - *psize) >+ { >+ *poffset = 0; >+ *psize = -1; >+ *pmax_size = -1; >+ >+ return exp; >+ } > > return exp; > } >--- gcc/testsuite/gcc.dg/pr82389.c.jj 2017-10-02 12:56:28.504213166 >+0200 >+++ gcc/testsuite/gcc.dg/pr82389.c 2017-10-02 12:57:46.820254081 +0200 >@@ -0,0 +1,13 @@ >+/* PR tree-optimization/82389 */ >+/* { dg-do compile { target lp64 } } */ >+/* { dg-options "-w -O3" } */ >+ >+struct S { char s[0x40000000]; } s; >+ >+void >+foo (struct S *p) >+{ >+ char b[0x0ffffffff0000000L]; >+ *(struct S *)&b[0x0fffffffef000000L] = s; >+ *p = *(struct S *)&b[0x0fffffffefffffffL]; >+} > > Jakub