summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-08 12:45:31 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-08 12:45:31 +0000
commiteeba931ec40a2b7a9ea41a44e9706e966f95a3ae (patch)
tree2126533d0ca55b44dcb679213e46878622b70f8d
parentfef98e29b98ff9f8eb89d4f08b6b6a14c1dd5da1 (diff)
downloadgcc-eeba931ec40a2b7a9ea41a44e9706e966f95a3ae.tar.gz
2007-05-08 Paul Thomas <pault@gcc.gnu.org>
PR fortran/31692 * trans-array.c (gfc_conv_array_parameter): Convert full array references to the result of the procedure enclusing the call. 2007-05-08 Paul Thomas <pault@gcc.gnu.org> PR fortran/31692 * gfortran.dg/actual_array_result_1.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124546 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-array.c38
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/actual_array_result_1.f9071
4 files changed, 115 insertions, 5 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7a145fa2d49..3fc67d70405 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,11 @@
2007-05-08 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/31692
+ * trans-array.c (gfc_conv_array_parameter): Convert full array
+ references to the result of the procedure enclusing the call.
+
+2007-05-08 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/29397
PR fortran/29400
* decl.c (add_init_expr_to_sym): Expand a scalar initializer
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 92fd67cccf5..4997673904f 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -4748,14 +4748,25 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
tree desc;
tree tmp;
tree stmt;
+ tree parent = DECL_CONTEXT (current_function_decl);
+ bool full_array_var, this_array_result;
gfc_symbol *sym;
stmtblock_t block;
+ full_array_var = (expr->expr_type == EXPR_VARIABLE
+ && expr->ref->u.ar.type == AR_FULL);
+ sym = full_array_var ? expr->symtree->n.sym : NULL;
+
+ /* Is this the result of the enclosing procedure? */
+ this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
+ if (this_array_result
+ && (sym->backend_decl != current_function_decl)
+ && (sym->backend_decl != parent))
+ this_array_result = false;
+
/* Passing address of the array if it is not pointer or assumed-shape. */
- if (expr->expr_type == EXPR_VARIABLE
- && expr->ref->u.ar.type == AR_FULL && g77)
+ if (full_array_var && g77 && !this_array_result)
{
- sym = expr->symtree->n.sym;
tmp = gfc_get_symbol_decl (sym);
if (sym->ts.type == BT_CHARACTER)
@@ -4784,8 +4795,25 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
}
}
- se->want_pointer = 1;
- gfc_conv_expr_descriptor (se, expr, ss);
+ if (this_array_result)
+ {
+ /* Result of the enclosing function. */
+ gfc_conv_expr_descriptor (se, expr, ss);
+ se->expr = build_fold_addr_expr (se->expr);
+
+ if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
+ && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
+ se->expr = gfc_conv_array_data (build_fold_indirect_ref (se->expr));
+
+ return;
+ }
+ else
+ {
+ /* Every other type of array. */
+ se->want_pointer = 1;
+ gfc_conv_expr_descriptor (se, expr, ss);
+ }
+
/* Deallocate the allocatable components of structures that are
not variable. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3c6d9c49bd9..1542977aced 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2007-05-08 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/31692
+ * gfortran.dg/actual_array_result_1.f90: New test.
+
+2007-05-08 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/29397
* gfortran.dg/parameter_array_init_1.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/actual_array_result_1.f90 b/gcc/testsuite/gfortran.dg/actual_array_result_1.f90
new file mode 100644
index 00000000000..cf79315cbb7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/actual_array_result_1.f90
@@ -0,0 +1,71 @@
+! { dg-do run }
+! PR fortan/31692
+! Passing array valued results to procedures
+!
+! Test case contributed by rakuen_himawari@yahoo.co.jp
+module one
+ integer :: flag = 0
+contains
+ function foo1 (n)
+ integer :: n
+ integer :: foo1(n)
+ if (flag == 0) then
+ call bar1 (n, foo1)
+ else
+ call bar2 (n, foo1)
+ end if
+ end function
+
+ function foo2 (n)
+ implicit none
+ integer :: n
+ integer,ALLOCATABLE :: foo2(:)
+ allocate (foo2(n))
+ if (flag == 0) then
+ call bar1 (n, foo2)
+ else
+ call bar2 (n, foo2)
+ end if
+ end function
+
+ function foo3 (n)
+ implicit none
+ integer :: n
+ integer,ALLOCATABLE :: foo3(:)
+ allocate (foo3(n))
+ foo3 = 0
+ call bar2(n, foo3(2:(n-1))) ! Check that sections are OK
+ end function
+
+ subroutine bar1 (n, array) ! Checks assumed size formal arg.
+ integer :: n
+ integer :: array(*)
+ integer :: i
+ do i = 1, n
+ array(i) = i
+ enddo
+ end subroutine
+
+ subroutine bar2(n, array) ! Checks assumed shape formal arg.
+ integer :: n
+ integer :: array(:)
+ integer :: i
+ do i = 1, size (array, 1)
+ array(i) = i
+ enddo
+ end subroutine
+end module
+
+program main
+ use one
+ integer :: n
+ n = 3
+ if(any (foo1(n) /= [ 1,2,3 ])) call abort()
+ if(any (foo2(n) /= [ 1,2,3 ])) call abort()
+ flag = 1
+ if(any (foo1(n) /= [ 1,2,3 ])) call abort()
+ if(any (foo2(n) /= [ 1,2,3 ])) call abort()
+ n = 5
+ if(any (foo3(n) /= [ 0,1,2,3,0 ])) call abort()
+end program
+! { dg-final { cleanup-modules "one" } }