aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/builtins.c8
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-70.c18
2 files changed, 25 insertions, 1 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3a3eb55..da25343 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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
index 0000000..087e255
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-70.c
@@ -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=" }