aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-08-18 08:33:21 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-08-18 08:33:21 +0000
commit97919ae7b65c192b0fdb6dfa6abdebd63a3f4ba9 (patch)
tree72321f7542701e8f11e627c812fb466857e6393f /gcc/tree-ssa-structalias.c
parent55715096b51c2cb7e9a9cd03bd562301b7867051 (diff)
downloadgcc-97919ae7b65c192b0fdb6dfa6abdebd63a3f4ba9.zip
gcc-97919ae7b65c192b0fdb6dfa6abdebd63a3f4ba9.tar.gz
gcc-97919ae7b65c192b0fdb6dfa6abdebd63a3f4ba9.tar.bz2
expr.c (get_inner_reference): Sign-extend the constant twos-complement offset before doing arbitrary...
2011-08-18 Richard Guenther <rguenther@suse.de> * expr.c (get_inner_reference): Sign-extend the constant twos-complement offset before doing arbitrary precision arithmetic on it. * tree-ssa-structalias.c (get_constraint_for_ptr_offset): Likewise. (get_constraint_for_1): Pass the offset of a MEM_REF unchanged to get_constraint_for_ptr_offset. From-SVN: r177847
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 79d4852..d69f14c 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2876,7 +2876,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
{
struct constraint_expr c;
unsigned int j, n;
- HOST_WIDE_INT rhsunitoffset, rhsoffset;
+ HOST_WIDE_INT rhsoffset;
/* If we do not do field-sensitive PTA adding offsets to pointers
does not change the points-to solution. */
@@ -2891,15 +2891,24 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
solution which includes all sub-fields of all pointed-to
variables of ptr. */
if (offset == NULL_TREE
- || !host_integerp (offset, 0))
+ || TREE_CODE (offset) != INTEGER_CST)
rhsoffset = UNKNOWN_OFFSET;
else
{
- /* Make sure the bit-offset also fits. */
- rhsunitoffset = TREE_INT_CST_LOW (offset);
- rhsoffset = rhsunitoffset * BITS_PER_UNIT;
- if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ /* Sign-extend the offset. */
+ double_int soffset
+ = double_int_sext (tree_to_double_int (offset),
+ TYPE_PRECISION (TREE_TYPE (offset)));
+ if (!double_int_fits_in_shwi_p (soffset))
rhsoffset = UNKNOWN_OFFSET;
+ else
+ {
+ /* Make sure the bit-offset also fits. */
+ HOST_WIDE_INT rhsunitoffset = soffset.low;
+ rhsoffset = rhsunitoffset * BITS_PER_UNIT;
+ if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ rhsoffset = UNKNOWN_OFFSET;
+ }
}
get_constraint_for_rhs (ptr, results);
@@ -3260,8 +3269,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,
{
struct constraint_expr cs;
varinfo_t vi, curr;
- tree off = convert_to_ptrofftype (TREE_OPERAND (t, 1));
- get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), off, results);
+ get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
+ TREE_OPERAND (t, 1), results);
do_deref (results);
/* If we are not taking the address then make sure to process