aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-10-02 17:48:55 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-10-02 17:48:55 +0200
commit476dec785da43401e5a34d80d2ed5ec61d3a9dd6 (patch)
tree995b3cb6383cb8b0d1a150842b336341e23b11bc /gcc
parentf240a230758a89d52799dc52606ec58963e248f2 (diff)
downloadgcc-476dec785da43401e5a34d80d2ed5ec61d3a9dd6.zip
gcc-476dec785da43401e5a34d80d2ed5ec61d3a9dd6.tar.gz
gcc-476dec785da43401e5a34d80d2ed5ec61d3a9dd6.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gcc.dg/pr82389.c13
-rw-r--r--gcc/tree-dfa.c17
4 files changed, 36 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ee72e4..bcd9ddd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2017-10-02 Jakub Jelinek <jakub@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.
+
PR tree-optimization/82387
PR tree-optimization/82388
PR tree-optimization/82389
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b75536..0d92d33 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2017-10-02 Jakub Jelinek <jakub@redhat.com>
+ * 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 0000000..eae5957
--- /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 2e65a44..db69bda 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;
}