re PR fortran/40850 (double free in nested types with allocatable components)
authorMikael Morin <mikael@gcc.gnu.org>
Wed, 23 Feb 2011 22:38:27 +0000 (22:38 +0000)
committerMikael Morin <mikael@gcc.gnu.org>
Wed, 23 Feb 2011 22:38:27 +0000 (22:38 +0000)
2011-02-23  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-23  Mikael Morin  <mikael@gcc.gnu.org>

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

From-SVN: r170445

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/fortran/trans.c
gcc/fortran/trans.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/nested_allocatables_1.f90 [new file with mode: 0644]

index 159b1be15c93ff817203793d9bf711713f75b469..96c5411e92224623a6bc70334b509c5ecb8b41da 100644 (file)
@@ -1,3 +1,11 @@
+2011-02-23  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-22  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/45743
index 4e901f27680b45be5942d428de27197b89e40192..ac08c42c94436a91a78dbe65271d1f7220af705b 100644 (file)
@@ -6097,10 +6097,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
index 1fd0dc130132b7881759804126c88e74bae00db7..27a352ab3bd4f0a524c2abc6220ea6b55f11f811 100644 (file)
@@ -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
index 40097a9f8203fb391d1aca5eecf8741932c99940..1536f2e806a1abb885aa5f563b72b9e0781c7245 100644 (file)
@@ -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.  */
index 20e9eed34ada1d1866acc000ec9c1b3f84d698b9..b2abbe7096159a124993aa4b8be77d3ce83ec1ee 100644 (file)
@@ -1,3 +1,8 @@
+2011-02-23  Mikael Morin  <mikael@gcc.gnu.org>
+
+       PR fortran/40850
+       * gfortran.dg/nested_allocatables_1.f90: New.
+
 2011-02-23  Nathan Froyd  <froydnj@codesourcery.com>
 
        PR c++/46868
diff --git a/gcc/testsuite/gfortran.dg/nested_allocatables_1.f90 b/gcc/testsuite/gfortran.dg/nested_allocatables_1.f90
new file mode 100644 (file)
index 0000000..607a883
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! PR fortran/40850
+! The code freeing allocatable components used to be put after the code
+! freeing the containing entity.
+!
+! Original test case by Marco Restelli <mrestelli@gmail.com>
+! Reduced by Daniel Franke <franke.daniel@gmail.com>
+!        and Janus Weil <janus@gcc.gnu.org>
+
+
+  type t
+    integer, allocatable :: d(:)
+  end type
+  type(t), allocatable :: a(:)
+
+  ! Big enough to make it fail
+  allocate(a(2 * 1024))
+  call sub( (/ a /) )
+
+contains
+
+  subroutine sub(b)
+    type(t) :: b(:)
+  end subroutine
+
+end
+