PR tree-optimization/82588 - missing -Warray-bounds on a excessively large index
PR tree-optimization/82583 - missing -Warray-bounds on out-of-bounds inner indic
gcc/ChangeLog:
PR tree-optimization/82588
PR tree-optimization/82583
* tree-vrp.c (check_array_ref): Handle flexible array members,
string literals, and inner indices.
(search_for_addr_array): Add detail to diagnostics.
gcc/testsuite/ChangeLog:
PR tree-optimization/82588
PR tree-optimization/82583
* c-c++-common/Warray-bounds.c: New test.
* gcc.dg/Warray-bounds-11.c: Adjust.
* gcc.dg/Warray-bounds-22.c: New test.
From-SVN: r254830
+2017-11-16 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/82588
+ PR tree-optimization/82583
+ * tree-vrp.c (check_array_ref): Handle flexible array members,
+ string literals, and inner indices.
+ (search_for_addr_array): Add detail to diagnostics.
+
2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836
+2017-11-16 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/82588
+ PR tree-optimization/82583
+ * c-c++-common/Warray-bounds.c: New test.
+ * gcc.dg/Warray-bounds-11.c: Adjust.
+ * gcc.dg/Warray-bounds-22.c: New test.
+
2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836
--- /dev/null
+/* PR tree-optimization/82588 - missing -Warray-bounds on an excessively
+ large index
+ { dg-do compile }
+ { dg-require-effective-target alloca }
+ { dg-options "-O2 -Warray-bounds -ftrack-macro-expansion=0" } */
+
+#define SIZE_MAX __SIZE_MAX__
+#define DIFF_MAX __PTRDIFF_MAX__
+#define DIFF_MIN (-DIFF_MAX - 1)
+
+#define offsetof(T, m) __builtin_offsetof (T, m)
+
+typedef __PTRDIFF_TYPE__ ssize_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern ssize_t signed_value (void)
+{
+ extern volatile ssize_t signed_value_source;
+ return signed_value_source;
+}
+
+extern size_t unsigned_value (void)
+{
+ extern volatile size_t unsigned_value_source;
+ return unsigned_value_source;
+}
+
+ssize_t signed_range (ssize_t min, ssize_t max)
+{
+ ssize_t val = signed_value ();
+ return val < min || max < val ? min : val;
+}
+
+typedef struct AX { int n; char ax[]; } AX;
+
+typedef struct A1 { int i; char a1[1]; } A1;
+typedef struct B { int i; struct A1 a1x[]; } B;
+
+void sink (int, ...);
+
+#define R(min, max) signed_range (min, max)
+#define T(expr) sink (0, expr)
+
+struct __attribute__ ((packed)) S16 { unsigned i: 16; };
+
+void farr_char (void)
+{
+ extern char ac[];
+
+ T (ac[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .char *\\\[]." } */
+ T (ac[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ac[0]);
+
+ T (ac[DIFF_MAX - 1]);
+ T (ac[DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ac[DIFF_MAX + (size_t)1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ac[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ac[R (DIFF_MAX - 1, DIFF_MAX)]);
+ T (ac[R (DIFF_MIN + 1, -1)]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ac[R (DIFF_MIN + 1, 0)]);
+ T (ac[R (-1, 0)]);
+ T (ac[R (-1, 1)]);
+}
+
+void farr_s16 (void)
+{
+ extern struct S16 ax[];
+
+ T (ax[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .(struct )?S16 *\\\[]." } */
+ T (ax[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ax[0]);
+
+ T (ax[DIFF_MAX / 2 - 1]);
+ T (ax[DIFF_MAX / 2]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ax[DIFF_MAX / 2 + (size_t)1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ax[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ax[R (DIFF_MIN, -1)]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ax[R (DIFF_MAX / 2 - 1, DIFF_MAX)]);
+ T (ax[R (DIFF_MAX / 2, DIFF_MAX)]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+}
+
+void farr_s16_7 (void)
+{
+ extern struct S16 ax_7[][7];
+
+ T (ax_7[0][DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .(struct )?S16 *\\\[7]." } */
+ T (ax_7[0][-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ax_7[0][0]);
+ T (ax_7[0][7]); /* { dg-warning "array subscript 7 is above array bounds of .(struct )?S16 *\\\[7]." } */
+ T (ax_7[0][8]); /* { dg-warning "array subscript 8 is above array bounds of .(struct )?S16 *\\\[7]." } */
+
+ T (ax_7[0][DIFF_MAX / 2]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ax_7[0][SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (ax_7[DIFF_MIN][0]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .(struct )?S16 *\\\[]\\\[7]." } */
+ T (ax_7[-1][0]); /* { dg-warning "array subscript -1 is below array bounds" } */
+
+ T (ax_7[DIFF_MAX / 2][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (ax_7[SIZE_MAX][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ ssize_t i = R (DIFF_MIN, -1);
+ T (ax_7[i][0]); /* { dg-warning "array subscript -1 is below array bounds" } */
+
+ T (ax_7[R (DIFF_MIN, -1)][0]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ax_7[R (DIFF_MIN, 0)][0]);
+ T (ax_7[R (-2, -1)][0]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (ax_7[R (-1, 0)][0]);
+ T (ax_7[R (-1, 1)][0]);
+ T (ax_7[R (-1, 7)][0]);
+ T (ax_7[R (-1, DIFF_MAX)][0]);
+
+ T (ax_7[R ( 1, DIFF_MAX)][0]);
+ T (ax_7[R (DIFF_MAX / 14 - 1, DIFF_MAX)][0]);
+
+ i = R (DIFF_MAX / 14, DIFF_MAX);
+ T (ax_7[i][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (ax_7[0][R (DIFF_MIN, 0)]);
+ T (ax_7[0][R (-1, 0)]);
+ T (ax_7[0][R (-1, 1)]);
+ T (ax_7[0][R (-1, 7)]);
+ T (ax_7[0][R (-1, DIFF_MAX)]);
+ T (ax_7[0][R (-1, DIFF_MAX)]);
+
+ T (ax_7[0][R (1, DIFF_MAX)]);
+ T (ax_7[0][R (7, DIFF_MAX)]); /* { dg-warning "array subscript 7 is above array bounds" } */
+
+}
+
+void farr_x_5_7 (void)
+{
+ extern struct S16 a[][5][7];
+
+ T (a[0][0][-3]); /* { dg-warning "array subscript -3 is below array bounds of .(struct )?S16 *\\\[7]." } */
+ T (a[0][-2][0]); /* { dg-warning "array subscript -2 is below array bounds of .(struct )?S16 *\\\[5]\\\[7]." } */
+ T (a[-1][0][0]); /* { dg-warning "array subscript -1 is below array bounds of .(struct )?S16 *\\\[]\\\[5]\\\[7]." } */
+ T (a[R (-4, -3)][0][0]); /* { dg-warning "array subscript -3 is below array bounds" } */
+ T (a[0][R (-3, -2)][0]); /* { dg-warning "array subscript -2 is below array bounds" } */
+ T (a[0][0][R (-2, -1)]); /* { dg-warning "array subscript -1 is below array bounds" } */
+}
+
+
+void fax (struct AX *p)
+{
+ T (p->ax[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->ax[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->ax[0]);
+ T (p->ax[DIFF_MAX - sizeof *p - 1]);
+ T (p->ax[DIFF_MAX - sizeof *p]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->ax[DIFF_MAX - sizeof *p + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->ax[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->ax[R (DIFF_MIN, -1)]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->ax[R (-1, 1)]);
+ T (p->ax[R (0, DIFF_MAX - 1)]);
+ T (p->ax[R (DIFF_MAX - 1, DIFF_MAX)]);/* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+}
+
+void fa1 (struct A1 *p)
+{
+ T (p->a1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1[0]);
+ T (p->a1[9]);
+ T (p->a1[DIFF_MAX - offsetof (A1, a1) - 1]);
+ T (p->a1[DIFF_MAX - offsetof (A1, a1)]);/* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1[DIFF_MAX - offsetof (A1, a1) + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+}
+
+void fb (struct B *p)
+{
+ T (p->a1x->a1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x->a1[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1x->a1[0]);
+ T (p->a1x->a1[9]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x->a1[DIFF_MAX - sizeof *p]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x->a1[DIFF_MAX - sizeof *p + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x->a1[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[1].a1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x[1].a1[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1x[1].a1[0]);
+ T (p->a1x[1].a1[9]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[1].a1[DIFF_MAX - sizeof *p]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[1].a1[DIFF_MAX - sizeof *p + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[1].a1[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[2].a1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x[2].a1[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1x[2].a1[0]);
+ T (p->a1x[2].a1[9]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[2].a1[DIFF_MAX - sizeof *p]);/* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[2].a1[DIFF_MAX - sizeof *p + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[2].a1[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[3].a1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x[3].a1[-1]); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1x[3].a1[0]);
+ T (p->a1x[3].a1[9]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[9].a1[0]);
+
+ enum { MAX = DIFF_MAX / sizeof *p->a1x - sizeof *p };
+
+ T (p->a1x[DIFF_MIN].a1); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x[-1].a1); /* { dg-warning "array subscript -1 is below array bounds" } */
+ T (p->a1x[MAX].a1);
+ T (p->a1x[MAX + 2].a1); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[DIFF_MAX].a1); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[SIZE_MAX].a1); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[DIFF_MIN].a1[0]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */
+ T (p->a1x[-1].a1[0]) /* { dg-warning "array subscript -1 is below array bounds" } */;
+ T (p->a1x[MAX - 1].a1[0]);
+ T (p->a1x[MAX].a1[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[MAX + 1].a1[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+
+ T (p->a1x[DIFF_MAX].a1[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+ T (p->a1x[SIZE_MAX].a1[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" } */
+}
+
+void f_cststring (int i)
+{
+ T (""[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .(const )?char *\\\[1]" "string" { xfail lp64 } } */
+ T (""[DIFF_MIN + 1]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds of .(const )?char *\\\[1]" "string" } */
+ T (""[-1]); /* { dg-warning "array subscript -1 is below array bounds of .(const )?char *\\\[1]" "string" } */
+ T (""[0]);
+ T (""[1]); /* { dg-warning "array subscript 1 is above array bounds of .(const )?char *\\\[1]" "string" } */
+ T ("0"[2]); /* { dg-warning "array subscript 2 is above array bounds of .(const )?char *\\\[2]" "string" } */
+ T ("012"[2]);
+ T ("012"[3]);
+ T ("012"[4]); /* { dg-warning "array subscript 4 is above array bounds of .(const )?char *\\\[4]" "string" } */
+ T ("0123"[DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds of .(const )?char *\\\[5]" "string" } */
+ T ("0123"[SIZE_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds of .(const )?char *\\\[5]" "string" } */
+}
+
+void fb_strlen (struct B *p)
+{
+#define strlen __builtin_strlen
+
+ T (strlen (&p->a1x[0].a1[2])); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "strlen" } */
+ T (strlen (p->a1x[0].a1 + 2)); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "strlen" { xfail *-*-* } } */
+}
+
+
+void f_vla (unsigned n)
+{
+ char vla[n];
+
+ T (vla[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" "vla" } */
+ T (vla[-1]); /* { dg-warning "array subscript -1 is below array bounds" "vla" } */
+ T (vla[0]);
+ T (vla[1]);
+ T (vla[n - 1]);
+ /* It would be nice to diagnose this. */
+ T (vla[n]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla[DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+}
void foo(int (*a)[3])
{
- (*a)[4] = 1; /* { dg-warning "subscript is above array bound" } */
+ (*a)[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
a[0][0] = 1; // ok
a[1][0] = 1; // ok
- a[1][4] = 1; /* { dg-warning "subscript is above array bound" } */
+ a[1][4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
int c[3] = { 0 };
- c[4] = 1; /* { dg-warning "subscript is above array bound" } */
+ c[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
- e[4] = 1; /* { dg-warning "subscript is above array bound" } */
+ e[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
struct f f;
- f.f[4] = 1; /* { dg-warning "subscript is above array bound" } */
+ f.f[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
struct h* h = malloc(sizeof(struct h) + 3 * sizeof(int));
struct h0* h0 = malloc(sizeof(struct h0) + 3 * sizeof(int));
h->j[4] = 1; // flexible array member
h0->j[4] = 1; // zero-sized array extension
- h1->j[4] = 1; /* { dg-warning "subscript is above array bound" } */
- h3->j[4] = 1; /* { dg-warning "subscript is above array bound" } */
+ h1->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
+ h3->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */
struct h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int));
struct h1b* h1b = malloc(sizeof(struct h1b) + 3 * sizeof(int));
struct h3b* h3b = malloc(sizeof(struct h3b));
// h0b->j[4] = 1;
- h1b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */
- h3b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */
+ h1b->j[4] = 1;; /* { dg-warning "subscript 4 is above array bound" } */
+ h3b->j[4] = 1;; /* { dg-warning "subscript 4 is above array bound" } */
// make sure nothing gets optimized away
bar(*a);
--- /dev/null
+/* PR tree-optimization/82588 - missing -Warray-bounds on an excessively
+ large index
+ { dg-do compile }
+ { dg-require-effective-target alloca }
+ { dg-options "-O2 -Warray-bounds -ftrack-macro-expansion=0" } */
+
+#define SIZE_MAX __SIZE_MAX__
+#define DIFF_MAX __PTRDIFF_MAX__
+#define DIFF_MIN (-DIFF_MAX - 1)
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern ptrdiff_t signed_value (void)
+{
+ extern volatile ptrdiff_t signed_value_source;
+ return signed_value_source;
+}
+
+ptrdiff_t signed_range (ptrdiff_t min, ptrdiff_t max)
+{
+ ptrdiff_t val = signed_value ();
+ return val < min || max < val ? min : val;
+}
+
+typedef struct AX { int n; char ax[]; } AX;
+
+typedef struct A1 { int i; char a1[1]; } A1;
+typedef struct B { int i; struct A1 a1x[]; } B;
+
+void sink (int, ...);
+
+#define T(expr) sink (0, (expr))
+
+void test_vla (unsigned m, unsigned n)
+{
+ char vla1[m];
+
+ T (vla1[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" "vla" } */
+ T (vla1[-1]); /* { dg-warning "array subscript -1 is below array bounds" "vla" } */
+ T (vla1[0]);
+ T (vla1[1]);
+ T (vla1[m - 1]);
+ /* It would be nice to diagnose this. */
+ T (vla1[m]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla1[DIFF_MAX - 1]);
+ T (vla1[DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+
+ ptrdiff_t i = signed_range (DIFF_MAX - 1, DIFF_MAX);
+ T (vla1[i]);
+
+ char vla2[m][n];
+
+ T (vla2[0][DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" "vla" } */
+ T (vla2[0][-1]); /* { dg-warning "array subscript -1 is below array bounds" "vla" } */
+ T (vla2[0][0]);
+ T (vla2[1][1]);
+ T (vla2[m - 1][n - 1]);
+ /* It would be nice to diagnose this. */
+ T (vla2[m][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla2[m + 1][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla2[0][n]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla2[0][n + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla2[m][n]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+ T (vla2[m + 1][n + 1]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "bug 82608" { xfail *-*-*} } */
+
+ T (vla2[0][DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+ T (vla2[DIFF_MAX][0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" { xfail *-*-* } } */
+ T (vla2[DIFF_MAX][DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+
+ struct S256 { char a[256]; } vla3[m];
+
+ T (vla3[DIFF_MIN].a[0]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" "vla" } */
+ T (vla3[-1].a[0]); /* { dg-warning "array subscript -1 is below array bounds" "vla" } */
+ T (vla3[0].a[0]);
+ T (vla3[1].a[0]);
+ T (vla3[m - 1].a[0]);
+ T (vla3[DIFF_MAX / 256 - 1].a[0]);
+ T (vla3[DIFF_MAX / 256].a[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+
+ i = signed_range (DIFF_MAX / 256 - 1, DIFF_MAX);
+ T (vla3[i].a[0]);
+
+ i = signed_range (DIFF_MAX / 256, DIFF_MAX);
+ T (vla3[i].a[0]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+
+ struct VLA { char vla[n]; } x;
+
+ T (x.vla[DIFF_MIN]); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" "vla" } */
+ T (x.vla[-1]); /* { dg-warning "array subscript -1 is below array bounds" "vla" } */
+ T (x.vla[0]);
+ T (x.vla[1]);
+ T (x.vla[n - 1]);
+ T (x.vla[DIFF_MAX - 1]);
+ T (x.vla[DIFF_MAX]); /* { dg-warning "array subscript \[0-9\]+ is above array bounds" "vla" } */
+}
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
+#include "tree-dfa.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
#include "stringpool.h"
#include "attribs.h"
#include "vr-values.h"
+#include "builtins.h"
/* Set of SSA names found live during the RPO traversal of the function
for still active basic-blocks. */
low_sub = up_sub = TREE_OPERAND (ref, 1);
up_bound = array_ref_up_bound (ref);
- /* Can not check flexible arrays. */
if (!up_bound
- || TREE_CODE (up_bound) != INTEGER_CST)
- return;
+ || TREE_CODE (up_bound) != INTEGER_CST
+ || (warn_array_bounds < 2
+ && array_at_struct_end_p (ref)))
+ {
+ /* Accesses to trailing arrays via pointers may access storage
+ beyond the types array bounds. For such arrays, or for flexible
+ array members, as well as for other arrays of an unknown size,
+ replace the upper bound with a more permissive one that assumes
+ the size of the largest object is PTRDIFF_MAX. */
+ tree eltsize = array_ref_element_size (ref);
+
+ /* FIXME: Handle VLAs. */
+ if (TREE_CODE (eltsize) != INTEGER_CST)
+ return;
- /* Accesses to trailing arrays via pointers may access storage
- beyond the types array bounds. */
- if (warn_array_bounds < 2
- && array_at_struct_end_p (ref))
- return;
+ tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
+
+ up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
+
+ tree arg = TREE_OPERAND (ref, 0);
+
+ HOST_WIDE_INT off;
+ if (get_addr_base_and_unit_offset (arg, &off))
+ up_bound_p1 = wide_int_to_tree (sizetype,
+ wi::sub (wi::to_wide (up_bound_p1),
+ off));
+
+ up_bound = int_const_binop (MINUS_EXPR, up_bound_p1,
+ build_int_cst (ptrdiff_type_node, 1));
+ }
+ else
+ up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
+ build_int_cst (TREE_TYPE (up_bound), 1));
low_bound = array_ref_low_bound (ref);
- up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
- build_int_cst (TREE_TYPE (up_bound), 1));
+
+ tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
/* Empty array. */
if (tree_int_cst_equal (low_bound, up_bound_p1))
{
warning_at (location, OPT_Warray_bounds,
- "array subscript is above array bounds");
+ "array subscript %E is above array bounds of %qT",
+ low_bound, artype);
TREE_NO_WARNING (ref) = 1;
}
&& tree_int_cst_le (low_sub, low_bound))
{
warning_at (location, OPT_Warray_bounds,
- "array subscript is outside array bounds");
+ "array subscript [%E, %E] is outside array bounds of %qT",
+ low_sub, up_sub, artype);
TREE_NO_WARNING (ref) = 1;
}
}
fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
- "array subscript is above array bounds");
+ "array subscript %E is above array bounds of %qT",
+ up_sub, artype);
TREE_NO_WARNING (ref) = 1;
}
else if (TREE_CODE (low_sub) == INTEGER_CST
fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
- "array subscript is below array bounds");
+ "array subscript %E is below array bounds of %qT",
+ low_sub, artype);
TREE_NO_WARNING (ref) = 1;
}
}
fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
- "array subscript is below array bounds");
+ "array subscript %wi is below array bounds of %qT",
+ idx.to_shwi (), TREE_TYPE (tem));
TREE_NO_WARNING (t) = 1;
}
else if (idx > (wi::to_offset (up_bound)
fprintf (dump_file, "\n");
}
warning_at (location, OPT_Warray_bounds,
- "array subscript is above array bounds");
+ "array subscript %wu is above array bounds of %qT",
+ idx.to_uhwi (), TREE_TYPE (tem));
TREE_NO_WARNING (t) = 1;
}
}