This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR39879 - [4.3/4.4/4.5 Regression] double free or corruption abort with gfortran


Dear All,

Since there in an interface assignment in the testcase, where the rhs
has a default initializer and rhs and lhs are variable expressions
involving the same variable, in resolve.c(resolve_ordinary_assign):
05962       /* Make a temporary rhs when there is a default initializer
05963          and rhs is the same symbol as the lhs.  */
05964       if (rhs->expr_type == EXPR_VARIABLE
05965             && rhs->symtree->n.sym->ts.type == BT_DERIVED
05966             && has_default_initializer (rhs->symtree->n.sym->ts.derived)
05967             && (lhs->symtree->n.sym == rhs->symtree->n.sym))
05968         code->ext.actual->next->expr = gfc_get_parentheses (rhs);

This would be fine except that in gfc_conv_procedure_call, the
temporary produced is only a shallow copy of the original but derived
type expressions with allocatable components have the components
deallocated, as they should.  What is needed in the above case is a
deep copy so that we do not wind up deallocating the variable on the
rhs of the assignment.  This is doen with the following patch:

Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 146772)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -2782,7 +2783,18 @@
 	      break;
 	    }

+	  if (e->expr_type == EXPR_OP
+		&& e->value.op.op == INTRINSIC_PARENTHESES
+		&& e->value.op.op1->expr_type == EXPR_VARIABLE)
+	    {
+	      tree local_tmp;
+	      local_tmp = gfc_evaluate_now (tmp, &se->pre);
+	      local_tmp = gfc_copy_alloc_comp (e->ts.derived, local_tmp,
tmp, parm_rank);
+	      gfc_add_expr_to_block (&se->post, local_tmp);
+	    }
+
 	  tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
+
 	  gfc_add_expr_to_block (&se->post, tmp);
         }

Not only does this fix the PR but it bootstraps and regtests on FC9/x86_i64.

With suitable testcase and ChangeLog entries, OK for trunk and, after
a week or so, 4.4 and 4.3?

Cheers

Paul


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]