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
......
...@@ -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 /* Accesses to trailing arrays via pointers may access storage
beyond the types array bounds. */ beyond the types array bounds. For such arrays, or for flexible
if (warn_array_bounds < 2 array members, as well as for other arrays of an unknown size,
&& array_at_struct_end_p (ref)) 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; return;
low_bound = array_ref_low_bound (ref); 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, up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
build_int_cst (TREE_TYPE (up_bound), 1)); build_int_cst (TREE_TYPE (up_bound), 1));
low_bound = array_ref_low_bound (ref);
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