[patch,fortran] Allocatable dummy-fix

Erik Edelmann erik.edelmann@iki.fi
Mon Mar 20 21:13:00 GMT 2006


:ADDPATCH fortran:

While working on the allocatable components stuff, I stumbled
across a bug for the allocatable dummy arguments:  If the actual
argument to a INTENT(OUT) allocatable dummy argument is itself a
dummy argument of the caller, we get an ICE:

erik:~$ cat test.f90
subroutine foo(x)
    real, allocatable, intent(inout) :: x(:)

    call bar(x)

contains

    subroutine bar(x)
        real, allocatable, intent(out) :: x(:)
    end subroutine bar

end subroutine foo
erik:~$ gfortran test.f90
test.f90: In function 'foo':
test.f90:4: internal compiler error: in
gfc_conv_descriptor_data_addr, at fortran/trans-array.c:186
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


The attached patch fixes this problem.  The solution is to, in
trans-expr.c (gfc_conv_function_call) in the code to deallocate
INTENT(OUT) arguments prior to a procedure call, use an indirect
reference through sym->backend_decl rather than sym->backend_decl
itself.

In addition, I've moved the getting of the tree representation of
the array to be deallocated out of trans-array.c
(gfc_trans_dealloc_allocated) to the caller.  This might make the
patch a little more complicated than it would have to be to fix
this bug, but I need this for the allocatable components, so I
decided to do it like this rather that doing something that I
would have to change later otherwise.

Regtested on Linux/x86.  Ok for trunk?


        Erik



2006-03-20  Erik Edelmann  <eedelman@gcc.gnu.org>

        * trans-array.c (gfc_trans_dealloc_allocated): Take a
          tree representation of the array to be deallocated as argument
          instead of its gfc_symbol.
          (gfc_trans_deferred_array): Update call to
          gfc_trans_dealloc_allocated.
        * trans-array.h (gfc_trans_dealloc_allocated): Update
          prototype.
        * trans-expr.c (gfc_conv_function_call): Update call to
          gfc_trans_dealloc_allocated, get indirect reference to dummy
          arguments.


2006-03-20  Erik Edelmann  <eedelman@gcc.gnu.org>

        * gfortran.dg/allocatable_dummy_1.f90: Also check that allocatable
          dummy arguments work when the actual argument is itself a dummy
          argument of the caller.
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/allocatable_dummy_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/allocatable_dummy_1.f90	(revision 112225)
+++ gcc/testsuite/gfortran.dg/allocatable_dummy_1.f90	(working copy)
@@ -33,7 +33,7 @@ contains
         integer, allocatable, intent(in)  :: x(:)
         integer, allocatable, intent(out) :: y(:)
         if (allocated(y)) call abort()
-        allocate (y(3))
+        call init(y)
         y = x
     end subroutine useit
 
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 112225)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -1920,7 +1920,10 @@ gfc_conv_function_call (gfc_se * se, gfc
               if (formal && formal->sym->attr.allocatable
                   && formal->sym->attr.intent == INTENT_OUT)
                 {
-                  tmp = gfc_trans_dealloc_allocated (arg->expr->symtree->n.sym);
+		  tmp = arg->expr->symtree->n.sym->backend_decl;
+		  if (arg->expr->symtree->n.sym->attr.dummy)
+                    tmp = build_fold_indirect_ref (tmp);
+                  tmp = gfc_trans_dealloc_allocated (tmp);
                   gfc_add_expr_to_block (&se->pre, tmp);
                 }
 
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c	(revision 112225)
+++ gcc/fortran/trans-array.c	(working copy)
@@ -4308,23 +4308,19 @@ gfc_conv_array_parameter (gfc_se * se, g
 }
 
 
-/* Generate code to deallocate the symbol 'sym', if it is allocated.  */
+/* Generate code to deallocate 'array', if it is allocated.  */
 
 tree
-gfc_trans_dealloc_allocated (gfc_symbol * sym)
+gfc_trans_dealloc_allocated (tree array)
 { 
   tree tmp;
-  tree descriptor;
   tree deallocate;
   stmtblock_t block;
 
-  gcc_assert (sym->attr.allocatable);
-
   gfc_start_block (&block);
-  descriptor = sym->backend_decl;
-  deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
+  deallocate = gfc_array_deallocate (array, null_pointer_node);
 
-  tmp = gfc_conv_descriptor_data_get (descriptor);
+  tmp = gfc_conv_descriptor_data_get (array);
   tmp = build2 (NE_EXPR, boolean_type_node, tmp,
                 build_int_cst (TREE_TYPE (tmp), 0));
   tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
@@ -4396,7 +4392,7 @@ gfc_trans_deferred_array (gfc_symbol * s
   /* Allocatable arrays need to be freed when they go out of scope.  */
   if (sym->attr.allocatable)
     {
-      tmp = gfc_trans_dealloc_allocated (sym);
+      tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
       gfc_add_expr_to_block (&fnblock, tmp);
     }
 
Index: gcc/fortran/trans-array.h
===================================================================
--- gcc/fortran/trans-array.h	(revision 112225)
+++ gcc/fortran/trans-array.h	(working copy)
@@ -41,8 +41,8 @@ tree gfc_trans_auto_array_allocation (tr
 tree gfc_trans_dummy_array_bias (gfc_symbol *, tree, tree);
 /* Generate entry and exit code for g77 calling convention arrays.  */
 tree gfc_trans_g77_array (gfc_symbol *, tree);
-/* Generate code to deallocate the symbol 'sym', if it is allocated.  */
-tree gfc_trans_dealloc_allocated (gfc_symbol * sym);
+/* Generate code to deallocate an array, if it is allocated.  */
+tree gfc_trans_dealloc_allocated (tree);
 /* Add initialization for deferred arrays.  */
 tree gfc_trans_deferred_array (gfc_symbol *, tree);
 /* Generate an initializer for a static pointer or allocatable array.  */


More information about the Fortran mailing list