This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/49324] Deep copy missing for array constructors of DT w/ allocatable components
- From: "burnus at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 9 Jun 2011 07:27:00 +0000
- Subject: [Bug fortran/49324] Deep copy missing for array constructors of DT w/ allocatable components
- Auto-submitted: auto-generated
- References: <bug-49324-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49324
Tobias Burnus <burnus at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Summary|Wrong result with |Deep copy missing for array
|constructor of derived |constructors of DT w/
|types w/ allocatable |allocatable components
|components |
--- Comment #4 from Tobias Burnus <burnus at gcc dot gnu.org> 2011-06-09 07:26:41 UTC ---
Paul: As you (with Erik) have implemented alloc components: Do you know the
purpose of the "if (r_is_var)"? (See bottom of this comment.) I wouldn't mind
if you could work on this PR as I would like to concentrate on other gfortran
and in particular urgent non-gfortran issues...
* * *
The cause of the failure is not really surprising; the issue is related to the
missing deep copy of the arguments:
D.1604 = (struct t[0:] * restrict) z.data;
(*(struct t[2] * restrict) atmp.8.data)[0] = x;
(*(struct t[2] * restrict) atmp.8.data)[1] = y;
(*D.1604)[(S.11 + D.1613) + D.1605]
= (*(struct t[2] * restrict) atmp.8.data)[S.11];
The code is OK if there are no allocatable components. However, with
allocatable components, one cannot simply assign the structure, but one needs
to deep copy the (allocatable) components. For ALLOCATE (..., SOURCE=...) and
for intrinsic assignment, a similar issue exists (and is mostly solved, except
for polymorphic variables, cf. PR46174).
If one looks at gfc_trans_scalar_assign, which is called in
gfc_trans_assignment_1, one finds:
5308 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
...
5341 /* Do a deep copy if the rhs is a variable, if it is not the
5342 same as the lhs. */
5343 if (r_is_var)
5344 {
5345 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
5346 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
5347 tmp);
5348 gfc_add_expr_to_block (&block, tmp);
5349 }
The "r_is_var" is given by (cf. trans-expr.c:6156):
expr_is_variable (expr2) || scalar_to_array
and as expr2 is an EXPR_ARRAY and not a variable ...
(For non-variables, the check "Are the rhs and the lhs the same?" does not make
sense, cf. trans-expr.c:5312-5319.)