re PR tree-optimization/83044 (ice in contains_struct_check)
PR tree-optimization/83044 * tree-vrp.c (vrp_prop::check_array_ref): If eltsize is not INTEGER_CST or is 0, clear up_bound{,_p1} and later ignore tests that need the upper bound. Subtract offset from get_addr_base_and_unit_offset only if positive and subtract it before division by eltsize rather than after it. * gcc.dg/pr83044.c: New test. * c-c++-common/Warray-bounds.c (fb): Fix up MAX value. From-SVN: r255054
This commit is contained in:
parent
a7d3cd407c
commit
ff4790688b
5 changed files with 54 additions and 19 deletions
|
@ -1,5 +1,12 @@
|
|||
2017-11-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/83044
|
||||
* tree-vrp.c (vrp_prop::check_array_ref): If eltsize is not
|
||||
INTEGER_CST or is 0, clear up_bound{,_p1} and later ignore tests
|
||||
that need the upper bound. Subtract offset from
|
||||
get_addr_base_and_unit_offset only if positive and subtract it
|
||||
before division by eltsize rather than after it.
|
||||
|
||||
PR debug/83084
|
||||
* valtrack.c (propagate_for_debug_subst, propagate_for_debug): Reset
|
||||
debug insns if they would contain UNSPEC_VOLATILE or volatile asm.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2017-11-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/83044
|
||||
* gcc.dg/pr83044.c: New test.
|
||||
* c-c++-common/Warray-bounds.c (fb): Fix up MAX value.
|
||||
|
||||
2017-11-22 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/79072
|
||||
|
|
|
@ -200,7 +200,7 @@ void fb (struct B *p)
|
|||
|
||||
T (p->a1x[9].a1[0]);
|
||||
|
||||
enum { MAX = DIFF_MAX / sizeof *p->a1x - sizeof *p };
|
||||
enum { MAX = (DIFF_MAX - sizeof *p) / sizeof *p->a1x };
|
||||
|
||||
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" } */
|
||||
|
|
14
gcc/testsuite/gcc.dg/pr83044.c
Normal file
14
gcc/testsuite/gcc.dg/pr83044.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* PR tree-optimization/83044 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wall -std=gnu89 -O2" } */
|
||||
|
||||
struct A { int b[0]; };
|
||||
struct B { struct A c[0]; };
|
||||
void bar (int *);
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
struct B d;
|
||||
bar (d.c->b);
|
||||
}
|
|
@ -4795,24 +4795,30 @@ vrp_prop::check_array_ref (location_t location, tree ref,
|
|||
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;
|
||||
if (TREE_CODE (eltsize) != INTEGER_CST
|
||||
|| integer_zerop (eltsize))
|
||||
{
|
||||
up_bound = NULL_TREE;
|
||||
up_bound_p1 = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
|
||||
tree arg = TREE_OPERAND (ref, 0);
|
||||
HOST_WIDE_INT off;
|
||||
|
||||
tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
|
||||
if (get_addr_base_and_unit_offset (arg, &off) && off > 0)
|
||||
maxbound = wide_int_to_tree (sizetype,
|
||||
wi::sub (wi::to_wide (maxbound),
|
||||
off));
|
||||
else
|
||||
maxbound = fold_convert (sizetype, maxbound);
|
||||
|
||||
up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
|
||||
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));
|
||||
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,
|
||||
|
@ -4823,7 +4829,7 @@ vrp_prop::check_array_ref (location_t location, tree ref,
|
|||
tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
|
||||
|
||||
/* Empty array. */
|
||||
if (tree_int_cst_equal (low_bound, up_bound_p1))
|
||||
if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
|
||||
{
|
||||
warning_at (location, OPT_Warray_bounds,
|
||||
"array subscript %E is above array bounds of %qT",
|
||||
|
@ -4843,7 +4849,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
|
|||
|
||||
if (vr && vr->type == VR_ANTI_RANGE)
|
||||
{
|
||||
if (TREE_CODE (up_sub) == INTEGER_CST
|
||||
if (up_bound
|
||||
&& TREE_CODE (up_sub) == INTEGER_CST
|
||||
&& (ignore_off_by_one
|
||||
? tree_int_cst_lt (up_bound, up_sub)
|
||||
: tree_int_cst_le (up_bound, up_sub))
|
||||
|
@ -4856,7 +4863,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
|
|||
TREE_NO_WARNING (ref) = 1;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (up_sub) == INTEGER_CST
|
||||
else if (up_bound
|
||||
&& TREE_CODE (up_sub) == INTEGER_CST
|
||||
&& (ignore_off_by_one
|
||||
? !tree_int_cst_le (up_sub, up_bound_p1)
|
||||
: !tree_int_cst_le (up_sub, up_bound)))
|
||||
|
|
Loading…
Add table
Reference in a new issue