HOST_WIDE_INT bitsize = -1;
HOST_WIDE_INT maxsize = -1;
tree size_tree = NULL_TREE;
- double_int bit_offset = double_int_zero;
+ 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)
case VIEW_CONVERT_EXPR:
break;
- bit_offset = double_int_zero;
+ 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:
- || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+ /* 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 ()
- == (signed) TREE_INT_CST_LOW
++ || !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)
{
exp = TREE_OPERAND (exp, 0);
}
- done:
- || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+ /* We need to deal with variable arrays ending structures. */
+ if (seen_variable_array_ref
+ && maxsize != -1
+ && (!bit_offset.fits_shwi ()
- == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
++ || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp)))
+ || (bit_offset.to_shwi () + maxsize
- if (!bit_offset.fits_shwi ())
++ == (signed) tree_to_uhwi (TYPE_SIZE (TREE_TYPE (exp))))))
+ maxsize = -1;
+
+ done:
+ if (!wi::fits_shwi_p (bit_offset))
{
*poffset = 0;
*psize = bitsize;