trans-expr.c (gfc_trans_scalar_assign): Rename argument, extend comment.

fortran/
	* trans-expr.c (gfc_trans_scalar_assign): Rename argument,
	extend comment.

From-SVN: r190392
This commit is contained in:
Mikael Morin 2012-08-14 16:35:09 +00:00
parent 2a573572eb
commit 2d4a44001c
2 changed files with 34 additions and 6 deletions

View file

@ -1,3 +1,8 @@
2012-08-14 Mikael Morin <mikael@gcc.gnu.org>
* trans-expr.c (gfc_trans_scalar_assign): Rename argument,
extend comment.
2012-08-14 Mikael Morin <mikael@gcc.gnu.org>
* gfortran.h (gfc_get_proc_ptr_comp): New prototype.

View file

@ -6307,11 +6307,34 @@ gfc_conv_string_parameter (gfc_se * se)
/* Generate code for assignment of scalar variables. Includes character
strings and derived types with allocatable components.
If you know that the LHS has no allocations, set dealloc to false. */
If you know that the LHS has no allocations, set dealloc to false.
DEEP_COPY has no effect if the typespec TS is not a derived type with
allocatable components. Otherwise, if it is set, an explicit copy of each
allocatable component is made. This is necessary as a simple copy of the
whole object would copy array descriptors as is, so that the lhs's
allocatable components would point to the rhs's after the assignment.
Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
necessary if the rhs is a non-pointer function, as the allocatable components
are not accessible by other means than the function's result after the
function has returned. It is even more subtle when temporaries are involved,
as the two following examples show:
1. When we evaluate an array constructor, a temporary is created. Thus
there is theoretically no alias possible. However, no deep copy is
made for this temporary, so that if the constructor is made of one or
more variable with allocatable components, those components still point
to the variable's: DEEP_COPY should be set for the assignment from the
temporary to the lhs in that case.
2. When assigning a scalar to an array, we evaluate the scalar value out
of the loop, store it into a temporary variable, and assign from that.
In that case, deep copying when assigning to the temporary would be a
waste of resources; however deep copies should happen when assigning from
the temporary to each array element: again DEEP_COPY should be set for
the assignment from the temporary to the lhs. */
tree
gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
bool l_is_temp, bool r_is_var, bool dealloc)
bool l_is_temp, bool deep_copy, bool dealloc)
{
stmtblock_t block;
tree tmp;
@ -6345,9 +6368,9 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
{
cond = NULL_TREE;
/* Are the rhs and the lhs the same? */
if (r_is_var)
if (deep_copy)
{
cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
gfc_build_addr_expr (NULL_TREE, lse->expr),
@ -6363,7 +6386,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
{
tmp = gfc_evaluate_now (lse->expr, &lse->pre);
tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
if (r_is_var)
if (deep_copy)
tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
tmp);
gfc_add_expr_to_block (&lse->post, tmp);
@ -6377,7 +6400,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
/* Do a deep copy if the rhs is a variable, if it is not the
same as the lhs. */
if (r_is_var)
if (deep_copy)
{
tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),