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> 2008-03-15 Bjoern Haase <bjoern.m.haase@web.de>
Anatoly Sokolov <aesok@post.ru> 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> 2008-03-15 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR testsuite/35478 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) ...@@ -1593,7 +1593,8 @@ widen_bitfield (tree val, tree field, tree var)
is the desired result type. */ is the desired result type. */
static tree 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 min_idx, idx, idx_type, elt_offset = integer_zero_node;
tree array_type, elt_type, elt_size; tree array_type, elt_type, elt_size;
...@@ -1693,11 +1694,15 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) ...@@ -1693,11 +1694,15 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
idx = fold_convert (idx_type, idx); idx = fold_convert (idx_type, idx);
/* We don't want to construct access past array bounds. For example /* We don't want to construct access past array bounds. For example
char *(c[4]); char *(c[4]);
c[3][2];
c[3][2]; should not be simplified into (*c)[14] or tree-vrp will give false should not be simplified into (*c)[14] or tree-vrp will
warning. */ give false warnings. The same is true for
if (domain_type && TYPE_MAX_VALUE (domain_type) 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_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST)
{ {
tree up_bound = TYPE_MAX_VALUE (domain_type); 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) ...@@ -1709,6 +1714,17 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
&& compare_tree_int (up_bound, 1) > 0) && compare_tree_int (up_bound, 1) > 0)
return NULL_TREE; 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); 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, ...@@ -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); new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE);
/* Recurse to possibly find the match. */ /* 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) if (ret)
return ret; return ret;
ret = maybe_fold_offset_to_component_ref (field_type, new_base, t, 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, ...@@ -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 = build1 (INDIRECT_REF, record_type, base);
base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE); 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) if (t)
return t; return t;
return maybe_fold_offset_to_component_ref (field_type, base, offset, 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) ...@@ -1893,7 +1911,7 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
{ {
if (base_is_ptr) if (base_is_ptr)
base = build1 (INDIRECT_REF, type, base); 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; return ret;
} }
...@@ -2070,7 +2088,7 @@ maybe_fold_stmt_addition (tree expr) ...@@ -2070,7 +2088,7 @@ maybe_fold_stmt_addition (tree expr)
ptd_type = TREE_TYPE (ptr_type); ptd_type = TREE_TYPE (ptr_type);
/* At which point we can try some of the same things as for indirects. */ /* 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) if (!t)
t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1, t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1,
ptd_type, false); 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