From: Jakub Jelinek Date: Mon, 2 Oct 2017 15:48:55 +0000 (+0200) Subject: tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1 if *poffset + *pmax_size... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=476dec785da43401e5a34d80d2ed5ec61d3a9dd6;p=gcc.git tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1 if *poffset + *pmax_size overflows in HOST_WIDE_INT. * 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. From-SVN: r253357 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ee72e4708e..bcd9ddd51ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-10-02 Jakub Jelinek + * 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. + PR tree-optimization/82387 PR tree-optimization/82388 PR tree-optimization/82389 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b75536209a..0d92d331478 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2017-10-02 Jakub Jelinek + * gcc.dg/pr82389.c: New test. + PR tree-optimization/82387 PR tree-optimization/82388 PR tree-optimization/82389 diff --git a/gcc/testsuite/gcc.dg/pr82389.c b/gcc/testsuite/gcc.dg/pr82389.c new file mode 100644 index 00000000000..eae5957cd0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr82389.c @@ -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]; +} diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 2e65a4443fc..db69bda32f6 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -654,7 +654,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, 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; }