diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 02:15:30 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 02:15:30 +0000 |
commit | 701c3ea94860c878112a2357bf576cce476f5223 (patch) | |
tree | e42c3f93e644d6029160f633bc071200be69bcc7 /gcc/tree-dfa.c | |
parent | a04a7bec5afd7a0c4d7f32d84f7fa4832600ce70 (diff) | |
parent | 793f83aeb2332046c68f1ea901230f353610fe46 (diff) | |
download | gcc-701c3ea94860c878112a2357bf576cce476f5223.tar.gz |
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@204436 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 93 |
1 files changed, 41 insertions, 52 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 13b27599aea..47413f2e2fe 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -389,7 +389,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, offset_int bit_offset = 0; HOST_WIDE_INT hbit_offset; bool seen_variable_array_ref = false; - tree base_type; /* First get the final access size from just the outermost expression. */ if (TREE_CODE (exp) == COMPONENT_REF) @@ -420,8 +419,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, and find the ultimate containing object. */ while (1) { - base_type = TREE_TYPE (exp); - switch (TREE_CODE (exp)) { case BIT_FIELD_REF: @@ -545,7 +542,38 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, case VIEW_CONVERT_EXPR: break; + case TARGET_MEM_REF: + /* Via the variable index or index2 we can reach the + whole object. Still hand back the decl here. */ + if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR + && (TMR_INDEX (exp) || TMR_INDEX2 (exp))) + { + exp = TREE_OPERAND (TMR_BASE (exp), 0); + bit_offset = 0; + maxsize = -1; + goto done; + } + /* Fallthru. */ case MEM_REF: + /* 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] + struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d] + 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. This needs to include possible trailing + padding that is there for alignment purposes. */ + if (seen_variable_array_ref + && maxsize != -1 + && (!bit_offset.fits_shwi () + || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))) + || (bit_offset.to_shwi () + maxsize + == (signed) tree_to_uhwi + (TYPE_SIZE (TREE_TYPE (exp)))))) + maxsize = -1; + /* Hand back the decl for MEM[&decl, off]. */ if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) { @@ -566,44 +594,23 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, } goto done; - case TARGET_MEM_REF: - /* Hand back the decl for MEM[&decl, off]. */ - if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR) - { - /* Via the variable index or index2 we can reach the - whole object. */ - if (TMR_INDEX (exp) || TMR_INDEX2 (exp)) - { - exp = TREE_OPERAND (TMR_BASE (exp), 0); - bit_offset = 0; - maxsize = -1; - goto done; - } - if (integer_zerop (TMR_OFFSET (exp))) - exp = TREE_OPERAND (TMR_BASE (exp), 0); - else - { - offset_int off = mem_ref_offset (exp); - off = wi::lshift (off, (BITS_PER_UNIT == 8 - ? 3 : exact_log2 (BITS_PER_UNIT))); - off += bit_offset; - if (wi::fits_shwi_p (off)) - { - bit_offset = off; - exp = TREE_OPERAND (TMR_BASE (exp), 0); - } - } - } - goto done; - default: goto done; } exp = TREE_OPERAND (exp, 0); } - done: + /* We need to deal with variable arrays ending structures. */ + if (seen_variable_array_ref + && maxsize != -1 + && (!bit_offset.fits_shwi () + || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))) + || (bit_offset.to_shwi () + maxsize + == (signed) tree_to_uhwi (TYPE_SIZE (TREE_TYPE (exp)))))) + maxsize = -1; + + done: if (!wi::fits_shwi_p (bit_offset)) { *poffset = 0; @@ -615,24 +622,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, hbit_offset = bit_offset.to_shwi (); - /* 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] - struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d] - 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. This needs to include possible trailing padding - that is there for alignment purposes. */ - - if (seen_variable_array_ref - && maxsize != -1 - && (!tree_fits_uhwi_p (TYPE_SIZE (base_type)) - || (hbit_offset + maxsize - == (signed) tree_to_uhwi (TYPE_SIZE (base_type))))) - maxsize = -1; - /* In case of a decl or constant base object we can do better. */ if (DECL_P (exp)) |