summaryrefslogtreecommitdiff
path: root/gcc/tree-dfa.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-06 02:15:30 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-06 02:15:30 +0000
commit701c3ea94860c878112a2357bf576cce476f5223 (patch)
treee42c3f93e644d6029160f633bc071200be69bcc7 /gcc/tree-dfa.c
parenta04a7bec5afd7a0c4d7f32d84f7fa4832600ce70 (diff)
parent793f83aeb2332046c68f1ea901230f353610fe46 (diff)
downloadgcc-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.c93
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))