diff options
author | Richard Guenther <rguenther@suse.de> | 2009-09-25 12:12:51 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-09-25 12:12:51 +0000 |
commit | 79441eca0eb2fc14297a09ac73fde9a629a72941 (patch) | |
tree | 43b83ef28811075b335e9d3175c045885975e100 /gcc/tree-dfa.c | |
parent | 6ef41fd08f9e000c1842a2309969fb8bb0f347c9 (diff) | |
download | gcc-79441eca0eb2fc14297a09ac73fde9a629a72941.tar.gz |
re PR middle-end/41463 (Another get_ref_base_and_extent problem)
2009-09-25 Richard Guenther <rguenther@suse.de>
PR middle-end/41463
* tree-dfa.c (get_ref_base_and_extent): Fix issue with trailing
arrays again.
* gcc.c-torture/execute/pr41463.c: New testcase.
From-SVN: r152167
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 3fd8477cf7e..847a6818b1b 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -799,8 +799,35 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, { HOST_WIDE_INT hthis_offset = TREE_INT_CST_LOW (this_offset); hthis_offset *= BITS_PER_UNIT; + hthis_offset + += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)); bit_offset += hthis_offset; - bit_offset += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)); + + /* If we had seen a variable array ref already and we just + referenced the last field of a struct or a union member + then we have to adjust maxsize by the padding at the end + of our field. */ + if (seen_variable_array_ref + && maxsize != -1) + { + tree stype = TREE_TYPE (TREE_OPERAND (exp, 0)); + tree next = TREE_CHAIN (field); + while (next && TREE_CODE (next) != FIELD_DECL) + next = TREE_CHAIN (next); + if (!next + || TREE_CODE (stype) != RECORD_TYPE) + { + tree fsize = DECL_SIZE_UNIT (field); + tree ssize = TYPE_SIZE_UNIT (stype); + if (host_integerp (fsize, 0) + && host_integerp (ssize, 0)) + maxsize += ((TREE_INT_CST_LOW (ssize) + - TREE_INT_CST_LOW (fsize)) + * BITS_PER_UNIT - hthis_offset); + else + maxsize = -1; + } + } } else { @@ -845,40 +872,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, else { tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0))); - /* Get at the array size but include trailing padding if - the array is the last element of a struct or union. */ - if (maxsize != -1 - && TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF) - { - tree cref = TREE_OPERAND (exp, 0); - tree field = TREE_OPERAND (cref, 1); - tree stype = TREE_TYPE (TREE_OPERAND (cref, 0)); - tree next = TREE_CHAIN (field); - while (next && TREE_CODE (next) != FIELD_DECL) - next = TREE_CHAIN (next); - if (!next - || TREE_CODE (stype) != RECORD_TYPE) - { - /* The size including padding is the size of - the whole structure minus the offset of the - array in it. */ - tree field_offset = component_ref_field_offset (cref); - if (field_offset - && host_integerp (field_offset, 0) - && host_integerp (TYPE_SIZE_UNIT (stype), 0)) - { - unsigned HOST_WIDE_INT as; - as = (((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (stype)) - - TREE_INT_CST_LOW (field_offset)) - * BITS_PER_UNIT) - - TREE_INT_CST_LOW - (DECL_FIELD_BIT_OFFSET (field))); - asize = build_int_cstu (sizetype, as); - } - else - asize = NULL_TREE; - } - } /* We need to adjust maxsize to the whole array bitsize. But we can subtract any constant offset seen so far, because that would get us outside of the array otherwise. */ @@ -902,7 +895,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, break; case VIEW_CONVERT_EXPR: - /* ??? We probably should give up here and bail out. */ break; default: @@ -925,10 +917,10 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, that is there for alignment purposes. */ if (seen_variable_array_ref - && (maxsize != -1 - && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) - && bit_offset + maxsize - == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))) + && maxsize != -1 + && (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) + || (bit_offset + maxsize + == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))) maxsize = -1; /* ??? Due to negative offsets in ARRAY_REF we can end up with |