Commit 1fd89060 by Richard Guenther Committed by Richard Biener

re PR middle-end/35593 (spurious warning "array subscript is below array bounds"…

re PR middle-end/35593 (spurious warning "array subscript is below array bounds" with void* function argument plus -O2)

2008-03-15  Richard Guenther  <rguenther@suse.de>

	PR middle-end/35593
	* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Make sure
	to not produce negative array indices if not allowed.  Add
	parameter to indicate that.
	(maybe_fold_offset_to_component_ref): Allow negative array
	indices only for the first member of a structure.
	(maybe_fold_offset_to_reference): Allow negative array indices.
	(maybe_fold_stmt_addition): Likewise.

	* g++.dg/warn/Warray-bounds-3.C: New testcase.

From-SVN: r133249
parent 693092fb
2008-03-15 Richard Guenther <rguenther@suse.de>
PR middle-end/35593
* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Make sure
to not produce negative array indices if not allowed. Add
parameter to indicate that.
(maybe_fold_offset_to_component_ref): Allow negative array
indices only for the first member of a structure.
(maybe_fold_offset_to_reference): Allow negative array indices.
(maybe_fold_stmt_addition): Likewise.
2008-03-15 Bjoern Haase <bjoern.m.haase@web.de>
Anatoly Sokolov <aesok@post.ru>
......
2008-03-15 Richard Guenther <rguenther@suse.de>
PR middle-end/35593
* g++.dg/warn/Warray-bounds-3.C: New testcase.
2008-03-15 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR testsuite/35478
/* { dg-do compile } */
/* { dg-options "-O2 -Wall" } */
extern void function(void * x);
struct A {
long x;
char d[0];
};
void test(A * a) {
function((char *)a - 4); /* { dg-bogus "below array bounds" } */
}
......@@ -1593,7 +1593,8 @@ widen_bitfield (tree val, tree field, tree var)
is the desired result type. */
static tree
maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type,
bool allow_negative_idx)
{
tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
tree array_type, elt_type, elt_size;
......@@ -1694,10 +1695,14 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
/* We don't want to construct access past array bounds. For example
char *(c[4]);
c[3][2]; should not be simplified into (*c)[14] or tree-vrp will give false
warning. */
if (domain_type && TYPE_MAX_VALUE (domain_type)
c[3][2];
should not be simplified into (*c)[14] or tree-vrp will
give false warnings. The same is true for
struct A { long x; char d[0]; } *a;
(char *)a - 4;
which should be not folded to &a->d[-8]. */
if (domain_type
&& TYPE_MAX_VALUE (domain_type)
&& TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST)
{
tree up_bound = TYPE_MAX_VALUE (domain_type);
......@@ -1709,6 +1714,17 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
&& compare_tree_int (up_bound, 1) > 0)
return NULL_TREE;
}
if (domain_type
&& TYPE_MIN_VALUE (domain_type))
{
if (!allow_negative_idx
&& TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST
&& tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type)))
return NULL_TREE;
}
else if (!allow_negative_idx
&& compare_tree_int (idx, 0) < 0)
return NULL_TREE;
return build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
}
......@@ -1805,7 +1821,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE);
/* Recurse to possibly find the match. */
ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type);
ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type,
f == TYPE_FIELDS (record_type));
if (ret)
return ret;
ret = maybe_fold_offset_to_component_ref (field_type, new_base, t,
......@@ -1827,7 +1844,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
base = build1 (INDIRECT_REF, record_type, base);
base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
t = maybe_fold_offset_to_array_ref (base, offset, orig_type,
f == TYPE_FIELDS (record_type));
if (t)
return t;
return maybe_fold_offset_to_component_ref (field_type, base, offset,
......@@ -1893,7 +1911,7 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
{
if (base_is_ptr)
base = build1 (INDIRECT_REF, type, base);
ret = maybe_fold_offset_to_array_ref (base, offset, orig_type);
ret = maybe_fold_offset_to_array_ref (base, offset, orig_type, true);
}
return ret;
}
......@@ -2070,7 +2088,7 @@ maybe_fold_stmt_addition (tree expr)
ptd_type = TREE_TYPE (ptr_type);
/* At which point we can try some of the same things as for indirects. */
t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type);
t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true);
if (!t)
t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1,
ptd_type, false);
......
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