summaryrefslogtreecommitdiff
path: root/gcc/tree-dfa.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-02-10 13:05:48 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-02-10 13:05:48 +0000
commit00e850451cfa2fee4f2c52442896522a6b61d3a1 (patch)
treec692ef13eeb559b4dc3cd81f57f1ced31dc093a3 /gcc/tree-dfa.c
parentb1d398fa050388b082c92dd5ded8f12c93f25154 (diff)
downloadgcc-00e850451cfa2fee4f2c52442896522a6b61d3a1.tar.gz
tree-dfa.c (get_ref_base_and_extent): When computing maxsize deal with structures that end in implicitly variable...
2006-02-10 Richard Guenther <rguenther@suse.de> * tree-dfa.c (get_ref_base_and_extent): When computing maxsize deal with structures that end in implicitly variable sized arrays. From-SVN: r110834
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r--gcc/tree-dfa.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 19453780d42..8339a942831 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -913,6 +913,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
HOST_WIDE_INT maxsize = -1;
tree size_tree = NULL_TREE;
tree bit_offset = bitsize_zero_node;
+ bool seen_variable_array_ref = false;
gcc_assert (!SSA_VAR_P (exp));
@@ -1004,6 +1005,11 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
fold_convert (bitsizetype, index),
bitsize_unit_node);
bit_offset = size_binop (PLUS_EXPR, bit_offset, index);
+
+ /* An array ref with a constant index up in the structure
+ hierarchy will constrain the size of any variable array ref
+ lower in the access hierarchy. */
+ seen_variable_array_ref = false;
}
else
{
@@ -1019,6 +1025,10 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
}
else
maxsize = -1;
+
+ /* Remember that we have seen an array ref with a variable
+ index. */
+ seen_variable_array_ref = true;
}
}
break;
@@ -1043,6 +1053,21 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
}
done:
+ /* We need to deal with variable arrays ending structures such as
+ struct { int length; int a[1]; } x; x.a[d]
+ struct { struct { int a; int b; } a[1]; } x; x.a[d].a
+ struct { struct { int a[1]; } a[1]; } x; x.a[0][d], x.a[d][0]
+ where we do not know maxsize for variable index accesses to
+ the array. The simplest way to conservatively deal with this
+ is to punt in the case that offset + maxsize reaches the
+ base type boundary. */
+ if (seen_variable_array_ref
+ && maxsize != -1
+ && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+ && TREE_INT_CST_LOW (bit_offset) + maxsize
+ == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
+ maxsize = -1;
+
/* ??? Due to negative offsets in ARRAY_REF we can end up with
negative bit_offset here. We might want to store a zero offset
in this case. */