summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/expr.c')
-rw-r--r--contrib/gcc/expr.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/contrib/gcc/expr.c b/contrib/gcc/expr.c
index c6bc426..1773fa1 100644
--- a/contrib/gcc/expr.c
+++ b/contrib/gcc/expr.c
@@ -5654,7 +5654,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
enum machine_mode mode = VOIDmode;
tree offset = size_zero_node;
tree bit_offset = bitsize_zero_node;
- tree tem;
/* First get the mode, signedness, and size. We do this from just the
outermost expression. */
@@ -5690,6 +5689,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
*pbitsize = tree_low_cst (size_tree, 1);
}
+ *pmode = mode;
+
/* Compute cumulative bit-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
while (1)
@@ -5774,21 +5775,69 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
done:
/* If OFFSET is constant, see if we can return the whole thing as a
- constant bit position. Otherwise, split it up. */
- if (host_integerp (offset, 0)
- && 0 != (tem = size_binop (MULT_EXPR,
- fold_convert (bitsizetype, offset),
- bitsize_unit_node))
- && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset))
- && host_integerp (tem, 0))
- *pbitpos = tree_low_cst (tem, 0), *poffset = 0;
- else
- *pbitpos = tree_low_cst (bit_offset, 0), *poffset = offset;
+ constant bit position. Make sure to handle overflow during
+ this conversion. */
+ if (host_integerp (offset, 0))
+ {
+ double_int tem = double_int_mul (tree_to_double_int (offset),
+ uhwi_to_double_int (BITS_PER_UNIT));
+ tem = double_int_add (tem, tree_to_double_int (bit_offset));
+ if (double_int_fits_in_shwi_p (tem))
+ {
+ *pbitpos = double_int_to_shwi (tem);
+ *poffset = NULL_TREE;
+ return exp;
+ }
+ }
+
+ /* Otherwise, split it up. */
+ *pbitpos = tree_low_cst (bit_offset, 0);
+ *poffset = offset;
- *pmode = mode;
return exp;
}
+/* Given an expression EXP that may be a COMPONENT_REF or an ARRAY_REF,
+ look for whether EXP or any nested component-refs within EXP is marked
+ as PACKED. */
+
+bool
+contains_packed_reference (tree exp)
+{
+ bool packed_p = false;
+
+ while (1)
+ {
+ switch (TREE_CODE (exp))
+ {
+ case COMPONENT_REF:
+ {
+ tree field = TREE_OPERAND (exp, 1);
+ packed_p = DECL_PACKED (field)
+ || TYPE_PACKED (TREE_TYPE (field))
+ || TYPE_PACKED (TREE_TYPE (exp));
+ if (packed_p)
+ goto done;
+ }
+ break;
+
+ case BIT_FIELD_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case VIEW_CONVERT_EXPR:
+ break;
+
+ default:
+ goto done;
+ }
+ exp = TREE_OPERAND (exp, 0);
+ }
+ done:
+ return packed_p;
+}
+
/* Return a tree of sizetype representing the size, in bytes, of the element
of EXP, an ARRAY_REF. */
OpenPOWER on IntegriCloud