diff mbox

[Fortran] PR fortran/40850 derived type allocatables freed before their components

Message ID 201102210053.49626.mikael.morin@sfr.fr
State New
Headers show

Commit Message

Mikael Morin Feb. 20, 2011, 11:53 p.m. UTC
Hello,

an oldie bug today; not a regression, but a wrong code.
So possibly suitable for stage4. 

What the patch does is use the new function `gfc_prepend_expr_to_block' 
function instead of `gfc_add_expr_to_block' whose code it duplicates, with the 
`front' flag of the helper `add_expr_to_chain' set to true instead of false. 

The patch fixes the comment 5 in the PR, but not the rest (comment 8). 

I will regression test this tomorrow; OK for trunk if it passes?

Mikael


2011-02-21  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/40850
	* trans.c (gfc_prepend_expr_to_block): New function.
	* trans.h (gfc_prepend_expr_to_block): Declare.
	* trans-array.c (gfc_conv_array_parameter): Replace gfc_add_expr_to_block
	with gfc_prepend_expr_to_block.


2011-02-21  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/40850
	* gfortran.dg/nested_allocatables_1.f90: New.

Comments

Mikael Morin Feb. 21, 2011, 1:10 p.m. UTC | #1
On Monday 21 February 2011 00:53:49 Mikael Morin wrote:
> I will regression test this tomorrow
> 
It didn't regress on x86_64-unknown-freebsd8.0. 
I forgot to add that I would appreciate if the testcase was confirmed to fail 
without the patch on various platforms (I have checked on FreeBSD 8.2), and if 
it doesn't how big the allocatable has to be to produce failure. 

Mikael
diff mbox

Patch

diff --git a/trans-array.c b/trans-array.c
index 4dc69d2..caac74f 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -6095,10 +6095,11 @@  gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
 	&& expr->ts.u.derived->attr.alloc_comp
 	&& expr->expr_type != EXPR_VARIABLE)
     {
-      tmp = build_fold_indirect_ref_loc (input_location,
-				     se->expr);
+      tmp = build_fold_indirect_ref_loc (input_location, se->expr);
       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
-      gfc_add_expr_to_block (&se->post, tmp);
+
+      /* The components shall be deallocated before their containing entity.  */
+      gfc_prepend_expr_to_block (&se->post, tmp);
     }
 
   if (g77 || (fsym && fsym->attr.contiguous
diff --git a/trans.c b/trans.c
index 1fd0dc1..27a352a 100644
--- a/trans.c
+++ b/trans.c
@@ -1090,7 +1090,8 @@  add_expr_to_chain (tree* chain, tree expr, bool front)
     *chain = expr;
 }
 
-/* Add a statement to a block.  */
+
+/* Add a statement at the end of a block.  */
 
 void
 gfc_add_expr_to_block (stmtblock_t * block, tree expr)
@@ -1100,6 +1101,16 @@  gfc_add_expr_to_block (stmtblock_t * block, tree expr)
 }
 
 
+/* Add a statement at the beginning of a block.  */
+
+void
+gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
+{
+  gcc_assert (block);
+  add_expr_to_chain (&block->head, expr, true);
+}
+
+
 /* Add a block the end of a block.  */
 
 void
diff --git a/trans.h b/trans.h
index 26ac003..6880775 100644
--- a/trans.h
+++ b/trans.h
@@ -396,6 +396,8 @@  void gfc_trans_vla_type_sizes (gfc_symbol *, stmtblock_t *);
 
 /* Add an expression to the end of a block.  */
 void gfc_add_expr_to_block (stmtblock_t *, tree);
+/* Add an expression to the beginning of a block.  */
+void gfc_prepend_expr_to_block (stmtblock_t *, tree);
 /* Add a block to the end of a block.  */
 void gfc_add_block_to_block (stmtblock_t *, stmtblock_t *);
 /* Add a MODIFY_EXPR to a block.  */