aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils2.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-05-28 15:24:12 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-05-28 15:24:12 +0000
commitfc7a823e1507110aba804cf94415155a8783e698 (patch)
treefb09192367caa4ff2977684a039b071404d51421 /gcc/ada/gcc-interface/utils2.c
parent318a4e6de8f20670c9f9e9dde02dc639f161f68c (diff)
downloadgcc-fc7a823e1507110aba804cf94415155a8783e698.zip
gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.gz
gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.bz2
gigi.h (gnat_stabilize_reference): Adjust.
* gcc-interface/gigi.h (gnat_stabilize_reference): Adjust. (rewrite_fn): Remove third parameter. (type_is_padding_self_referential): New inline predicate. (return_type_with_variable_size_p): Likewise. * gcc-interface/decl.c (allocatable_size_p): More around. (cannot_be_superflat_p): Rename into... (cannot_be_superflat ): ...this. (initial_value_needs_conversion): New predicate. (gnat_to_gnu_entity): Invoke type_is_padding_self_referential, initial_value_needs_conversion and adjust to above renaming. For a renaming, force the materialization if the inner expression is compound. Adjust calls to elaborate_reference and build a compound expression if needed. (struct er_dat): Add N field. (elaborate_reference_1): Remove N parameter and adjust. (elaborate_reference): Add INIT parameter and pass it in the call to gnat_rewrite_reference. Adjust initial expression. * gcc-interface/trans.c (Call_to_gnu): Treat renamings the same way as regular object declarations when it comes to creating a temporary. Adjust call to gnat_stabilize_reference and build a compound expression if needed. Invoke return_type_with_variable_size_p. (gnat_to_gnu): Invoke type_is_padding_self_referential. In case #4, return a call to a function unmodified if it returns with variable size and is also the initial expression in an object declaration. * gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: Use the RHS' type if it is a call to a function that returns with variable size. (build_unary_op): Invoke type_is_padding_self_referential. (gnat_stabilize_reference_1): Remove N parameter and adjust. (gnat_stabilize_reference): Add INIT parameter and pass it in the call to gnat_rewrite_reference. (gnat_rewrite_reference): Remove N, add INIT parameter and adjust. <COMPOUND_EXPR>: New case. From-SVN: r223834
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r--gcc/ada/gcc-interface/utils2.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index edbcc53..cc2c645 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -923,13 +923,10 @@ build_binary_op (enum tree_code op_code, tree result_type,
operation_type = left_type;
}
- /* If we have a call to a function that returns an unconstrained type
- with default discriminant on the RHS, use the RHS type (which is
- padded) as we cannot compute the size of the actual assignment. */
+ /* If we have a call to a function that returns with variable size, use
+ the RHS type in case we want to use the return slot optimization. */
else if (TREE_CODE (right_operand) == CALL_EXPR
- && TYPE_IS_PADDING_P (right_type)
- && CONTAINS_PLACEHOLDER_P
- (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (right_type)))))
+ && return_type_with_variable_size_p (right_type))
operation_type = right_type;
/* Find the best type to use for copying between aggregate types. */
@@ -1420,10 +1417,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
/* If INNER is a padding type whose field has a self-referential
size, convert to that inner type. We know the offset is zero
and we need to have that type visible. */
- if (TYPE_IS_PADDING_P (TREE_TYPE (inner))
- && CONTAINS_PLACEHOLDER_P
- (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS
- (TREE_TYPE (inner))))))
+ if (type_is_padding_self_referential (TREE_TYPE (inner)))
inner = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (inner))),
inner);
@@ -2663,7 +2657,7 @@ gnat_protect_expr (tree exp)
argument to force evaluation of everything. */
static tree
-gnat_stabilize_reference_1 (tree e, void *data, int n)
+gnat_stabilize_reference_1 (tree e, void *data)
{
const bool force = *(bool *)data;
enum tree_code code = TREE_CODE (e);
@@ -2688,7 +2682,7 @@ gnat_stabilize_reference_1 (tree e, void *data, int n)
&& TYPE_IS_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e, 0))))
result
= build3 (code, type,
- gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n),
+ gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data),
TREE_OPERAND (e, 1), TREE_OPERAND (e, 2));
/* If the expression has side-effects, then encase it in a SAVE_EXPR
so that it will only be evaluated once. */
@@ -2704,15 +2698,15 @@ gnat_stabilize_reference_1 (tree e, void *data, int n)
/* Recursively stabilize each operand. */
result
= build2 (code, type,
- gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n),
- gnat_stabilize_reference_1 (TREE_OPERAND (e, 1), data, n));
+ gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data),
+ gnat_stabilize_reference_1 (TREE_OPERAND (e, 1), data));
break;
case tcc_unary:
/* Recursively stabilize each operand. */
result
= build1 (code, type,
- gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data, n));
+ gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), data));
break;
default:
@@ -2728,21 +2722,22 @@ gnat_stabilize_reference_1 (tree e, void *data, int n)
/* This is equivalent to stabilize_reference in tree.c but we know how to
handle our own nodes and we take extra arguments. FORCE says whether to
- force evaluation of everything. */
+ force evaluation of everything in REF. INIT is set to the first arm of
+ a COMPOUND_EXPR present in REF, if any. */
tree
-gnat_stabilize_reference (tree ref, bool force)
+gnat_stabilize_reference (tree ref, bool force, tree *init)
{
- return gnat_rewrite_reference (ref, gnat_stabilize_reference_1, &force);
+ return
+ gnat_rewrite_reference (ref, gnat_stabilize_reference_1, &force, init);
}
/* Rewrite reference REF and call FUNC on each expression within REF in the
- process. DATA is passed unmodified to FUNC and N is bumped each time it
- is passed to FUNC, so FUNC is guaranteed to see a given N only once per
- reference to be rewritten. */
+ process. DATA is passed unmodified to FUNC. INIT is set to the first
+ arm of a COMPOUND_EXPR present in REF, if any. */
tree
-gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n)
+gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, tree *init)
{
tree type = TREE_TYPE (ref);
enum tree_code code = TREE_CODE (ref);
@@ -2764,25 +2759,25 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n)
result
= build1 (code, type,
gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, data,
- n));
+ init));
break;
case INDIRECT_REF:
case UNCONSTRAINED_ARRAY_REF:
- result = build1 (code, type, func (TREE_OPERAND (ref, 0), data, n));
+ result = build1 (code, type, func (TREE_OPERAND (ref, 0), data));
break;
case COMPONENT_REF:
result = build3 (COMPONENT_REF, type,
gnat_rewrite_reference (TREE_OPERAND (ref, 0), func,
- data, n),
+ data, init),
TREE_OPERAND (ref, 1), NULL_TREE);
break;
case BIT_FIELD_REF:
result = build3 (BIT_FIELD_REF, type,
gnat_rewrite_reference (TREE_OPERAND (ref, 0), func,
- data, n),
+ data, init),
TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2));
break;
@@ -2791,11 +2786,18 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n)
result
= build4 (code, type,
gnat_rewrite_reference (TREE_OPERAND (ref, 0), func, data,
- n + 1),
- func (TREE_OPERAND (ref, 1), data, n),
+ init),
+ func (TREE_OPERAND (ref, 1), data),
TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
break;
+ case COMPOUND_EXPR:
+ gcc_assert (*init == NULL_TREE);
+ *init = TREE_OPERAND (ref, 0);
+ /* We expect only the pattern built in Call_to_gnu. */
+ gcc_assert (DECL_P (TREE_OPERAND (ref, 1)));
+ return TREE_OPERAND (ref, 1);
+
case CALL_EXPR:
{
/* This can only be an atomic load. */
@@ -2808,9 +2810,9 @@ gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, int n)
if (TREE_CODE (t) == ADDR_EXPR)
t = build1 (ADDR_EXPR, TREE_TYPE (t),
gnat_rewrite_reference (TREE_OPERAND (t, 0), func, data,
- n));
+ init));
else
- t = func (t, data, n);
+ t = func (t, data);
t = fold_convert (TREE_TYPE (CALL_EXPR_ARG (ref, 0)), t);
result = build_call_expr (TREE_OPERAND (CALL_EXPR_FN (ref), 0), 2,