http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45451

--- Comment #13 from Tobias Burnus <burnus at gcc dot gnu.org> 2010-10-24 
21:42:33 UTC ---
(In reply to comment #12)
> If one looks at the dump

Scratch that part. In one case one allocates the component (integr(4)*4) in the
other case the type, i.e. the array descriptor.

The actual issue is that only a shallow copy is done:

      (void) __builtin_memcpy ((void *) a.$data, (void *) &acsr, 48);

Thus, a.$data->irp.data and acsr.irp.data point to the same memory. Of course,
this will fail at
  finally
      if (acsr.irp.data != 0B)
          __builtin_free ((void *) acsr.irp.data);
      if (a.$data != 0B)
          if (a.$data->irp.data != 0B)
              __builtin_free ((void *) a.$data->irp.data);

The problem is in trans-stmt.c's gfc_trans_allocate:

      if (code->expr3 && !code->expr3->mold)
        {
          /* Initialization via SOURCE block
             (or static default initializer).  */
          gfc_expr *rhs = gfc_copy_expr (code->expr3);
          if (al->expr->ts.type == BT_CLASS)
              [...]
              tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz);
            }
          else
            tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
                                        rhs, false, false);

The gfc_trans_assignment properly takes care of allocatable components (cf. PR
43018) while a simple memcopy does not.


The following works - though I am not sure whether it is the correct patch.
Janus, what do you think?

--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -4489,15 +4489,9 @@ gfc_trans_allocate (gfc_code * code)
          gfc_expr *rhs = gfc_copy_expr (code->expr3);
          if (al->expr->ts.type == BT_CLASS)
            {
-             gfc_se dst,src;
              if (rhs->ts.type == BT_CLASS)
                gfc_add_component_ref (rhs, "$data");
-             gfc_init_se (&dst, NULL);
-             gfc_init_se (&src, NULL);
-             gfc_conv_expr (&dst, expr);
-             gfc_conv_expr (&src, rhs);
-             gfc_add_block_to_block (&block, &src.pre);
-             tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz);
+             tmp = gfc_trans_assignment (expr, rhs, false, false);
            }
          else
            tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),

Reply via email to