/* 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;
   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),
        {
          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);
 
       /* 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),