aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2016-06-06 09:44:11 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2016-06-06 09:44:11 +0000
commit62801a777ae288d0b01792ec8f85cded7b6d9df3 (patch)
treed8b7d032b53a272332300754ebabd26c255b7dfb
parentf1ff07ec096c3b59ef3d883e00dd4a840314eaf8 (diff)
downloadgcc-62801a777ae288d0b01792ec8f85cded7b6d9df3.zip
gcc-62801a777ae288d0b01792ec8f85cded7b6d9df3.tar.gz
gcc-62801a777ae288d0b01792ec8f85cded7b6d9df3.tar.bz2
utils2.c (build_call_alloc_dealloc): Do not substitute placeholder expressions here but...
* gcc-interface/utils2.c (build_call_alloc_dealloc): Do not substitute placeholder expressions here but... * gcc-interface/trans.c (gnat_to_gnu) <N_Free_Statement>: ...here. Make an exception to the protection of a CALL_EXPR result with an unconstrained type only in the same cases as Call_to_gnu. From-SVN: r237125
-rw-r--r--gcc/ada/ChangeLog8
-rw-r--r--gcc/ada/gcc-interface/trans.c29
-rw-r--r--gcc/ada/gcc-interface/utils2.c2
3 files changed, 26 insertions, 13 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a958655..f4ce315 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,13 @@
2016-06-06 Eric Botcazou <ebotcazou@adacore.com>
+ * gcc-interface/utils2.c (build_call_alloc_dealloc): Do not substitute
+ placeholder expressions here but...
+ * gcc-interface/trans.c (gnat_to_gnu) <N_Free_Statement>: ...here.
+ Make an exception to the protection of a CALL_EXPR result with an
+ unconstrained type only in the same cases as Call_to_gnu.
+
+2016-06-06 Eric Botcazou <ebotcazou@adacore.com>
+
* gcc-interface/trans.c (gnat_to_gnu): Rework special code dealing
with boolean rvalues and set the location directly. Do not set the
location in the other cases for a simple name.
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index d0071d3..5f4d3a6 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -7640,10 +7640,11 @@ gnat_to_gnu (Node_Id gnat_node)
else
gnu_actual_obj_type = gnu_obj_type;
+ tree gnu_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
+ gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_ptr);
+
gnu_result
- = build_call_alloc_dealloc (gnu_ptr,
- TYPE_SIZE_UNIT (gnu_actual_obj_type),
- gnu_obj_type,
+ = build_call_alloc_dealloc (gnu_ptr, gnu_size, gnu_obj_type,
Procedure_To_Call (gnat_node),
Storage_Pool (gnat_node),
gnat_node);
@@ -7729,16 +7730,22 @@ gnat_to_gnu (Node_Id gnat_node)
N_Raise_Constraint_Error));
}
- /* If the result has side-effects and is of an unconstrained type, make a
- SAVE_EXPR so that we can be sure it will only be referenced once. But
- this is useless for a call to a function that returns an unconstrained
- type with default discriminant, as we cannot compute the size of the
- actual returned object. We must do this before any conversions. */
+ /* If the result has side-effects and is of an unconstrained type, protect
+ the expression in case it will be referenced multiple times, i.e. for
+ its value and to compute the size of an object. But do it neither for
+ an object nor a renaming declaration, nor a return statement of a call
+ to a function that returns an unconstrained record type with default
+ discriminant, because there is no size to be computed in these cases
+ and this will create a useless temporary. We must do this before any
+ conversions. */
if (TREE_SIDE_EFFECTS (gnu_result)
- && !(TREE_CODE (gnu_result) == CALL_EXPR
- && type_is_padding_self_referential (TREE_TYPE (gnu_result)))
&& (TREE_CODE (gnu_result_type) == UNCONSTRAINED_ARRAY_TYPE
- || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))))
+ || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type)))
+ && !(TREE_CODE (gnu_result) == CALL_EXPR
+ && type_is_padding_self_referential (TREE_TYPE (gnu_result))
+ && (Nkind (Parent (gnat_node)) == N_Object_Declaration
+ || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration
+ || Nkind (Parent (gnat_node)) == N_Simple_Return_Statement)))
gnu_result = gnat_protect_expr (gnu_result);
/* Now convert the result to the result type, unless we are in one of the
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 67799df..a0804e8 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -2268,8 +2268,6 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
Entity_Id gnat_proc, Entity_Id gnat_pool,
Node_Id gnat_node)
{
- gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
-
/* Explicit proc to call ? This one is assumed to deal with the type
alignment constraints. */
if (Present (gnat_proc))