[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