diff options
author | Richard Guenther <rguenther@suse.de> | 2008-06-04 08:28:20 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-06-04 08:28:20 +0000 |
commit | 0e19bf429e8fdfe384b9dad2f3bbfd0c15524cda (patch) | |
tree | 33671adf33b9edd9e36895c610444498f3801a41 /gcc/tree-ssa-structalias.c | |
parent | c750c990445c1437910c18b9e79fba5713a770c1 (diff) | |
download | gcc-0e19bf429e8fdfe384b9dad2f3bbfd0c15524cda.zip gcc-0e19bf429e8fdfe384b9dad2f3bbfd0c15524cda.tar.gz gcc-0e19bf429e8fdfe384b9dad2f3bbfd0c15524cda.tar.bz2 |
tree-ssa-structalias.c (handle_ptr_arith): Correctly handle negative or non-representable offsets.
2008-06-04 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (handle_ptr_arith): Correctly handle
negative or non-representable offsets.
* gcc.c-torture/execute/20080604-1.c: New testcase.
From-SVN: r136351
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r-- | gcc/tree-ssa-structalias.c | 44 |
1 files changed, 12 insertions, 32 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 0e42214..570c173 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3531,8 +3531,7 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr) unsigned int i = 0; unsigned int j = 0; VEC (ce_s, heap) *temp = NULL; - unsigned int rhsoffset = 0; - bool unknown_addend = false; + unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset; if (TREE_CODE (expr) != POINTER_PLUS_EXPR) return false; @@ -3541,13 +3540,18 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr) op1 = TREE_OPERAND (expr, 1); gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0))); - get_constraint_for (op0, &temp); + /* If the offset is not a non-negative integer constant that fits + in a HOST_WIDE_INT, we cannot handle it here. */ + if (!host_integerp (op1, 1)) + return false; - /* Handle non-constants by making constraints from integer. */ - if (TREE_CODE (op1) == INTEGER_CST) - rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT; - else - unknown_addend = true; + /* Make sure the bit-offset also fits. */ + rhsunitoffset = TREE_INT_CST_LOW (op1); + rhsoffset = rhsunitoffset * BITS_PER_UNIT; + if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + return false; + + get_constraint_for (op0, &temp); for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++) for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++) @@ -3564,30 +3568,6 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr) c2->var = temp->id; c2->offset = 0; } - else if (unknown_addend) - { - /* Can't handle *a + integer where integer is unknown. */ - if (c2->type != SCALAR) - { - struct constraint_expr intc; - intc.var = integer_id; - intc.offset = 0; - intc.type = SCALAR; - process_constraint (new_constraint (*c, intc)); - } - else - { - /* We known it lives somewhere within c2->var. */ - varinfo_t tmp = get_varinfo (c2->var); - for (; tmp; tmp = tmp->next) - { - struct constraint_expr tmpc = *c2; - c2->var = tmp->id; - c2->offset = 0; - process_constraint (new_constraint (*c, tmpc)); - } - } - } else c2->offset = rhsoffset; process_constraint (new_constraint (*c, *c2)); |