aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2014-01-25 10:51:47 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2014-01-25 10:51:47 +0000
commit88293f0384de09f14bdbb55afa363cc72006f9b2 (patch)
tree9af0986644e6850485cbac6372243960c42ad5af /gcc/ada/gcc-interface/utils.c
parentae56e44284592b1e8cca35f870e0240e65e141c5 (diff)
downloadgcc-88293f0384de09f14bdbb55afa363cc72006f9b2.zip
gcc-88293f0384de09f14bdbb55afa363cc72006f9b2.tar.gz
gcc-88293f0384de09f14bdbb55afa363cc72006f9b2.tar.bz2
utils.c (convert_to_fat_pointer): Un-obfuscate the conversion from a thin pointer with a shifted value.
* gcc-interface/utils.c (convert_to_fat_pointer): Un-obfuscate the conversion from a thin pointer with a shifted value. * gcc-interface/utils2.c (gnat_build_constructor): Propagate the read-only flag from the values onto the result. (gnat_invariant_expr): Accept read-only CONSTRUCTORs. From-SVN: r207073
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 69ea026..014fe36 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4352,7 +4352,7 @@ convert_to_fat_pointer (tree type, tree expr)
tree template_type = TREE_TYPE (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))));
tree p_array_type = TREE_TYPE (TYPE_FIELDS (type));
tree etype = TREE_TYPE (expr);
- tree template_tree;
+ tree template_addr;
vec<constructor_elt, va_gc> *v;
vec_alloc (v, 2);
@@ -4395,31 +4395,43 @@ convert_to_fat_pointer (tree type, tree expr)
tree field = TYPE_FIELDS (TREE_TYPE (etype));
expr = gnat_protect_expr (expr);
- if (TREE_CODE (expr) == ADDR_EXPR)
- expr = TREE_OPERAND (expr, 0);
- else
+
+ /* If we have a TYPE_UNCONSTRAINED_ARRAY attached to the RECORD_TYPE,
+ the thin pointer value has been shifted so we shift it back to get
+ the template address. */
+ if (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
{
- /* If we have a TYPE_UNCONSTRAINED_ARRAY attached to the RECORD_TYPE,
- the thin pointer value has been shifted so we first need to shift
- it back to get the template address. */
- if (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
- expr
- = build_binary_op (POINTER_PLUS_EXPR, etype, expr,
- fold_build1 (NEGATE_EXPR, sizetype,
- byte_position
- (DECL_CHAIN (field))));
- expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+ template_addr
+ = build_binary_op (POINTER_PLUS_EXPR, etype, expr,
+ fold_build1 (NEGATE_EXPR, sizetype,
+ byte_position
+ (DECL_CHAIN (field))));
+ template_addr
+ = fold_convert (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))),
+ template_addr);
}
- template_tree = build_component_ref (expr, NULL_TREE, field, false);
- expr = build_unary_op (ADDR_EXPR, NULL_TREE,
- build_component_ref (expr, NULL_TREE,
- DECL_CHAIN (field), false));
+ /* Otherwise we explicitly take the address of the fields. */
+ else
+ {
+ expr = build_unary_op (INDIRECT_REF, NULL_TREE, expr);
+ template_addr
+ = build_unary_op (ADDR_EXPR, NULL_TREE,
+ build_component_ref (expr, NULL_TREE, field,
+ false));
+ expr = build_unary_op (ADDR_EXPR, NULL_TREE,
+ build_component_ref (expr, NULL_TREE,
+ DECL_CHAIN (field),
+ false));
+ }
}
/* Otherwise, build the constructor for the template. */
else
- template_tree = build_template (template_type, TREE_TYPE (etype), expr);
+ template_addr
+ = build_unary_op (ADDR_EXPR, NULL_TREE,
+ build_template (template_type, TREE_TYPE (etype),
+ expr));
/* The final result is a constructor for the fat pointer.
@@ -4433,11 +4445,8 @@ convert_to_fat_pointer (tree type, tree expr)
Note that the call to "build_template" above is still fine because it
will only refer to the provided TEMPLATE_TYPE in this case. */
- CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type),
- convert (p_array_type, expr));
- CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)),
- build_unary_op (ADDR_EXPR, NULL_TREE,
- template_tree));
+ CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type), convert (p_array_type, expr));
+ CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)), template_addr);
return gnat_build_constructor (type, v);
}