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>
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
......
......@@ -57,19 +57,19 @@ struct h3b {
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));
......@@ -78,15 +78,15 @@ void foo(int (*a)[3])
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);
......
/* 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
#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"
......@@ -65,6 +66,7 @@ along with GCC; see the file COPYING3. If not see
#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. */
......@@ -4781,26 +4783,51 @@ vrp_prop::check_array_ref (location_t location, tree ref,
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;
}
......@@ -4824,7 +4851,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
&& 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;
}
}
......@@ -4840,7 +4868,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
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
......@@ -4853,7 +4882,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
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;
}
}
......@@ -4908,7 +4938,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location)
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)
......@@ -4921,7 +4952,8 @@ vrp_prop::search_for_addr_array (tree t, location_t location)
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;
}
}
......
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