[multiple changes]
authorPaul Thomas <pault@gcc.gnu.org>
Fri, 25 Nov 2016 12:23:43 +0000 (12:23 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Fri, 25 Nov 2016 12:23:43 +0000 (12:23 +0000)
2016-11-25  Andre Vehreschild  <vehre@gcc.gnu.org>
Paul Thomas  <pault@gcc.gnu.org>

PR fortran/78293
* trans-expr.c (gfc_conv_procedure_call): Prepend deallocation
of alloctable components to post, rather than adding to
se->post.
* trans-stmt.c (gfc_trans_allocate): Move deallocation of expr3
allocatable components so that all expr3s are visited.

2016-11-25  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/78293
* gfortran.dg/allocatable_function_10.f90: New test.
* gfortran.dg/class_array_15.f03: Increase builtin_free count
from 11 to 12.

From-SVN: r242875

gcc/fortran/ChangeLog
gcc/fortran/trans-expr.c
gcc/fortran/trans-stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/allocatable_function_10.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/class_array_15.f03

index 4c27f1b622e61bc8bfe729dffa26253c607b2d03..737a22c906ffb9837539a95c47e08788b7a4f2dc 100644 (file)
@@ -1,3 +1,20 @@
+2016-11-25  Andre Vehreschild  <vehre@gcc.gnu.org>
+           Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/78293
+       * trans-expr.c (gfc_conv_procedure_call): Prepend deallocation
+       of alloctable components to post, rather than adding to
+       se->post.
+       * trans-stmt.c (gfc_trans_allocate): Move deallocation of expr3
+       allocatable components so that all expr3s are visited.
+
+2016-11-25  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/78293
+       * gfortran.dg/allocatable_function_10.f90: New test.
+       * gfortran.dg/class_array_15.f03: Increase builtin_free count
+       from 11 to 12.
+
 2016-11-24  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/78500
index 1331b07a2380f4fa354158d3295ce3d05a3d575a..1c2d5e1ed3aad3e1cbe33491cba790b4f1711e87 100644 (file)
@@ -5568,7 +5568,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
          tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
 
-         gfc_add_expr_to_block (&se->post, tmp);
+         gfc_prepend_expr_to_block (&post, tmp);
         }
 
       /* Add argument checking of passing an unallocated/NULL actual to
index 490b18dae31eb4e567abd0eadf48d37eb8ee35af..19ecf68528517255be4840f2496c500b9722604a 100644 (file)
@@ -5684,17 +5684,6 @@ gfc_trans_allocate (gfc_code * code)
            }
          gfc_add_modify_loc (input_location, &block, var, tmp);
 
-         /* Deallocate any allocatable components after all the allocations
-            and assignments of expr3 have been completed.  */
-         if (code->expr3->ts.type == BT_DERIVED
-             && code->expr3->rank == 0
-             && code->expr3->ts.u.derived->attr.alloc_comp)
-           {
-             tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
-                                              var, 0);
-             gfc_add_expr_to_block (&post, tmp);
-           }
-
          expr3 = var;
          if (se.string_length)
            /* Evaluate it assuming that it also is complicated like expr3.  */
@@ -5705,6 +5694,20 @@ gfc_trans_allocate (gfc_code * code)
          expr3 = se.expr;
          expr3_len = se.string_length;
        }
+
+      /* Deallocate any allocatable components in expressions that use a
+        temporary, i.e. are not of expr-type EXPR_VARIABLE or force the
+        use of a temporary, after the assignment of expr3 is completed.  */
+      if ((code->expr3->ts.type == BT_DERIVED
+          || code->expr3->ts.type == BT_CLASS)
+         && (code->expr3->expr_type != EXPR_VARIABLE || temp_var_needed)
+         && code->expr3->ts.u.derived->attr.alloc_comp)
+       {
+         tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
+                                          expr3, code->expr3->rank);
+         gfc_prepend_expr_to_block (&post, tmp);
+       }
+
       /* Store what the expr3 is to be used for.  */
       if (e3_is == E3_UNSET)
        e3_is = expr3 != NULL_TREE ?
index fe43b97635f801abfce1ed6f9aa920f4a39f0f81..87d6fca44dc5ab2d11bb5d368c7c1e6c8e9416cd 100644 (file)
@@ -1,3 +1,10 @@
+2016-11-25  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/78293
+       * gfortran.dg/allocatable_function_10.f90: New test.
+       * gfortran.dg/class_array_15.f03: Increase builtin_free count
+       from 11 to 12.
+
 2016-11-25  Bin Cheng  <bin.cheng@arm.com>
 
        PR middle-end/78507
@@ -45,7 +52,7 @@
 2016-11-25  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        * gcc.dg/pr64277.c: Use __INT32_TYPE__ for targets
-       with sizeof(int) < 4. 
+       with sizeof(int) < 4.
 
 2016-11-24  Martin Sebor  <msebor@redhat.com>
 
diff --git a/gcc/testsuite/gfortran.dg/allocatable_function_10.f90 b/gcc/testsuite/gfortran.dg/allocatable_function_10.f90
new file mode 100644 (file)
index 0000000..8d17197
--- /dev/null
@@ -0,0 +1,46 @@
+! { dg-do run }
+!
+! Test the fix for PR78293. The deallocations are present at the
+! end of the main programme to aid memory leak searching. The
+! allocation in 'tt' leaked memory from an intermediate temporary
+! for the array constructor.
+!
+! Contributed by Andrew Benson  <abensonca@gmail.com>
+!
+module m
+  implicit none
+
+  type t
+     integer, allocatable, dimension(:) :: r
+  end type t
+
+contains
+
+  function tt(a,b)
+    implicit none
+    type(t), allocatable, dimension(:) :: tt
+    type(t), intent(in), dimension(:) :: a,b
+    allocate(tt, source = [a,b])
+  end function tt
+
+  function ts(arg)
+    implicit none
+    type(t), allocatable, dimension(:) :: ts
+    integer, intent(in) :: arg(:)
+    allocate(ts(1))
+    allocate(ts(1)%r, source = arg)
+    return
+  end function ts
+
+end module m
+
+program p
+  use m
+  implicit none
+  type(t), dimension(2) :: c
+  c=tt(ts([99,199,1999]),ts([42,142]))
+  if (any (c(1)%r .ne. [99,199,1999])) call abort
+  if (any (c(2)%r .ne. [42,142])) call abort
+  deallocate(c(1)%r)
+  deallocate(c(2)%r)
+end program p
index 85716f905cb20e7bd87abcf609d268737a762bea..fd9e04c28285fb796d1df8a48ab8ac51490bde91 100644 (file)
@@ -115,4 +115,4 @@ subroutine pr54992  ! This test remains as the original.
   bh => bhGet(b,instance=2)
   if (loc (b) .ne. loc(bh%hostNode)) call abort
 end
-! { dg-final { scan-tree-dump-times "builtin_free" 11 "original" } }
+! { dg-final { scan-tree-dump-times "builtin_free" 12 "original" } }