aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2005-11-17 11:35:00 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2005-11-17 11:35:00 +0000
commit0bc52d42a8a8c376f9d13a9ea1d5739b6dc3a195 (patch)
treefa01127a0e850334616461c97e66569538042b89 /gcc/fold-const.c
parentf92af607242414c1ee85a5eab0a9cf131bda0996 (diff)
downloadgcc-0bc52d42a8a8c376f9d13a9ea1d5739b6dc3a195.zip
gcc-0bc52d42a8a8c376f9d13a9ea1d5739b6dc3a195.tar.gz
gcc-0bc52d42a8a8c376f9d13a9ea1d5739b6dc3a195.tar.bz2
re PR middle-end/24851 (f2c miscompilation)
2005-11-16 Richard Guenther <rguenther@suse.de> PR middle-end/24851 * fold-const.c (extract_array_ref): Return byte offset in all cases. (fold_binary): Fold &x[a] CMP &x[b] to a*sizeof(*x) CMP b*sizeof(*x) to get correct overflow behavior. * gcc.c-torture/execute/pr24851.c: New testcase. From-SVN: r107117
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0e74391..343cfae 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5537,7 +5537,8 @@ constant_boolean_node (int value, tree type)
offset to the appropriate trees. If there is no offset,
offset is set to NULL_TREE. Base will be canonicalized to
something you can get the element type from using
- TREE_TYPE (TREE_TYPE (base)). */
+ TREE_TYPE (TREE_TYPE (base)). Offset will be the offset
+ in bytes to the base. */
static bool
extract_array_ref (tree expr, tree *base, tree *offset)
@@ -5573,8 +5574,10 @@ extract_array_ref (tree expr, tree *base, tree *offset)
tree op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == ARRAY_REF)
{
+ tree idx = TREE_OPERAND (op0, 1);
*base = TREE_OPERAND (op0, 0);
- *offset = TREE_OPERAND (op0, 1);
+ *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
+ array_ref_element_size (op0));
}
else
{
@@ -8888,25 +8891,21 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
- if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))
- && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))))
- offset0 = NULL_TREE;
- if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))
- && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))))
- offset1 = NULL_TREE;
+ /* Handle no offsets on both sides specially. */
if (offset0 == NULL_TREE
&& offset1 == NULL_TREE)
+ return fold_build2 (code, type, integer_zero_node,
+ integer_zero_node);
+
+ if (!offset0 || !offset1
+ || TREE_TYPE (offset0) == TREE_TYPE (offset1))
{
- offset0 = integer_zero_node;
- offset1 = integer_zero_node;
+ if (offset0 == NULL_TREE)
+ offset0 = build_int_cst (TREE_TYPE (offset1), 0);
+ if (offset1 == NULL_TREE)
+ offset1 = build_int_cst (TREE_TYPE (offset0), 0);
+ return fold_build2 (code, type, offset0, offset1);
}
- else if (offset0 == NULL_TREE)
- offset0 = build_int_cst (TREE_TYPE (offset1), 0);
- else if (offset1 == NULL_TREE)
- offset1 = build_int_cst (TREE_TYPE (offset0), 0);
-
- if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
- return fold_build2 (code, type, offset0, offset1);
}
}