Commit 8a5ee94a by Martin Sebor Committed by Martin Sebor

PR tree-optimization/82588 - missing -Warray-bounds on a excessively large index

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
parent 79cefe9d
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> 2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836 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> 2017-11-16 Nathan Sidwell <nathan@acm.org>
PR c++/82836 PR c++/82836
......
/* 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" } */
}
...@@ -57,19 +57,19 @@ struct h3b { ...@@ -57,19 +57,19 @@ struct h3b {
void foo(int (*a)[3]) 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[0][0] = 1; // ok
a[1][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 }; 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; 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 h* h = malloc(sizeof(struct h) + 3 * sizeof(int));
struct h0* h0 = malloc(sizeof(struct h0) + 3 * sizeof(int)); struct h0* h0 = malloc(sizeof(struct h0) + 3 * sizeof(int));
...@@ -78,15 +78,15 @@ void foo(int (*a)[3]) ...@@ -78,15 +78,15 @@ void foo(int (*a)[3])
h->j[4] = 1; // flexible array member h->j[4] = 1; // flexible array member
h0->j[4] = 1; // zero-sized array extension h0->j[4] = 1; // zero-sized array extension
h1->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 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 h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int));
struct h1b* h1b = malloc(sizeof(struct h1b) + 3 * sizeof(int)); struct h1b* h1b = malloc(sizeof(struct h1b) + 3 * sizeof(int));
struct h3b* h3b = malloc(sizeof(struct h3b)); struct h3b* h3b = malloc(sizeof(struct h3b));
// h0b->j[4] = 1; // h0b->j[4] = 1;
h1b->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 is above array bound" } */ h3b->j[4] = 1;; /* { dg-warning "subscript 4 is above array bound" } */
// make sure nothing gets optimized away // make sure nothing gets optimized away
bar(*a); bar(*a);
......
/* 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" } */
}
...@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-iterator.h" #include "gimple-iterator.h"
#include "gimple-walk.h" #include "gimple-walk.h"
#include "tree-cfg.h" #include "tree-cfg.h"
#include "tree-dfa.h"
#include "tree-ssa-loop-manip.h" #include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h" #include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h" #include "tree-ssa-loop.h"
...@@ -65,6 +66,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -65,6 +66,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h" #include "stringpool.h"
#include "attribs.h" #include "attribs.h"
#include "vr-values.h" #include "vr-values.h"
#include "builtins.h"
/* Set of SSA names found live during the RPO traversal of the function /* Set of SSA names found live during the RPO traversal of the function
for still active basic-blocks. */ for still active basic-blocks. */
...@@ -4781,26 +4783,51 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4781,26 +4783,51 @@ vrp_prop::check_array_ref (location_t location, tree ref,
low_sub = up_sub = TREE_OPERAND (ref, 1); low_sub = up_sub = TREE_OPERAND (ref, 1);
up_bound = array_ref_up_bound (ref); up_bound = array_ref_up_bound (ref);
/* Can not check flexible arrays. */
if (!up_bound if (!up_bound
|| TREE_CODE (up_bound) != INTEGER_CST) || TREE_CODE (up_bound) != INTEGER_CST
return; || (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 tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
beyond the types array bounds. */
if (warn_array_bounds < 2 up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
&& array_at_struct_end_p (ref))
return; 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); 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. */ /* Empty array. */
if (tree_int_cst_equal (low_bound, up_bound_p1)) if (tree_int_cst_equal (low_bound, up_bound_p1))
{ {
warning_at (location, OPT_Warray_bounds, 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_NO_WARNING (ref) = 1;
} }
...@@ -4824,7 +4851,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4824,7 +4851,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
&& tree_int_cst_le (low_sub, low_bound)) && tree_int_cst_le (low_sub, low_bound))
{ {
warning_at (location, OPT_Warray_bounds, 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; TREE_NO_WARNING (ref) = 1;
} }
} }
...@@ -4840,7 +4868,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4840,7 +4868,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
warning_at (location, OPT_Warray_bounds, 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; TREE_NO_WARNING (ref) = 1;
} }
else if (TREE_CODE (low_sub) == INTEGER_CST else if (TREE_CODE (low_sub) == INTEGER_CST
...@@ -4853,7 +4882,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4853,7 +4882,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
warning_at (location, OPT_Warray_bounds, 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; TREE_NO_WARNING (ref) = 1;
} }
} }
...@@ -4908,7 +4938,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location) ...@@ -4908,7 +4938,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
warning_at (location, OPT_Warray_bounds, 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; TREE_NO_WARNING (t) = 1;
} }
else if (idx > (wi::to_offset (up_bound) else if (idx > (wi::to_offset (up_bound)
...@@ -4921,7 +4952,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location) ...@@ -4921,7 +4952,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
warning_at (location, OPT_Warray_bounds, 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; TREE_NO_WARNING (t) = 1;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment