diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/utils.cc | 17 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.cc | 11 |
2 files changed, 22 insertions, 6 deletions
diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 1448716..9212827 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -5259,7 +5259,7 @@ convert (tree type, tree expr) : size_zero_node; tree byte_diff = size_diffop (type_pos, etype_pos); - expr = build1 (NOP_EXPR, type, expr); + expr = fold_convert (type, expr); if (integer_zerop (byte_diff)) return expr; @@ -5267,6 +5267,21 @@ convert (tree type, tree expr) fold_convert (sizetype, byte_diff)); } + /* If converting from a thin pointer with zero offset from the base to + a pointer to the array, add the offset of the array field. */ + if (TYPE_IS_THIN_POINTER_P (etype) + && !TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype))) + { + tree arr_field = DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype))); + + if (TREE_TYPE (type) == TREE_TYPE (arr_field)) + { + expr = fold_convert (type, expr); + return build_binary_op (POINTER_PLUS_EXPR, type, expr, + byte_position (arr_field)); + } + } + /* If converting fat pointer to normal or thin pointer, get the pointer to the array and then convert it. */ if (TYPE_IS_FAT_POINTER_P (etype)) diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index 99e5927..58418ea 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -1628,11 +1628,12 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) = size_binop (PLUS_EXPR, offset, size_int (bits_to_bytes_round_down (bitpos))); - /* Take the address of INNER, convert it to a pointer to our type - and add the offset. */ - inner = build_unary_op (ADDR_EXPR, - build_pointer_type (TREE_TYPE (operand)), - inner); + /* Take the address of INNER, formally convert it to a pointer + to the operand type, and finally add the offset. */ + inner = build_unary_op (ADDR_EXPR, NULL_TREE, inner); + inner + = fold_convert (build_pointer_type (TREE_TYPE (operand)), + inner); result = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (inner), inner, offset); break; |