PR middle-end/97556 - ICE on excessively large index into a multidimensional array
authorMartin Sebor <msebor@redhat.com>
Fri, 30 Oct 2020 19:04:29 +0000 (13:04 -0600)
committerMartin Sebor <msebor@redhat.com>
Fri, 30 Oct 2020 19:04:29 +0000 (13:04 -0600)
gcc/ChangeLog:

PR middle-end/97556
* builtins.c (access_ref::add_offset): Cap offset lower bound
to at most the the upper bound.

gcc/testsuite/ChangeLog:

PR middle-end/97556
* gcc.dg/Warray-bounds-70.c: New test.

gcc/builtins.c
gcc/testsuite/gcc.dg/Warray-bounds-70.c [new file with mode: 0644]

index 3a3eb5562df7a8e9c737da265ab99ec3c1139477..da25343beb1b9eccdb05c6031555dd7204d4628b 100644 (file)
@@ -321,7 +321,13 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
       offrng[1] = maxoff;
       offset_int absmax = wi::abs (max);
       if (offrng[0] < absmax)
-       offrng[0] += min;
+       {
+         offrng[0] += min;
+         /* Cap the lower bound at the upper (set to MAXOFF above)
+            to avoid inadvertently recreating an inverted range.  */
+         if (offrng[1] < offrng[0])
+           offrng[0] = offrng[1];
+       }
       else
        offrng[0] = 0;
     }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-70.c b/gcc/testsuite/gcc.dg/Warray-bounds-70.c
new file mode 100644 (file)
index 0000000..087e255
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR middle-end/97556 - ICE on excessively large index into a multidimensional
+   array
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+#define SIZE_MAX __SIZE_MAX__
+
+typedef __SIZE_TYPE__ size_t;
+
+char a[1][3];
+
+void f (int c)
+{
+  size_t i = c ? SIZE_MAX / 2 : SIZE_MAX;
+  a[i][0] = 0;                          // { dg-warning "\\\[-Warray-bounds" }
+}
+
+// { dg-prune-output "\\\[-Wstringop-overflow=" }