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:
Jakub Jelinek 2017-11-22 13:35:26 +01:00 committed by Jakub Jelinek
parent a7d3cd407c
commit ff4790688b
5 changed files with 54 additions and 19 deletions

View file

@ -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.

View file

@ -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

View file

@ -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" } */

View 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);
}

View file

@ -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)))