Commit fc90a8f2 by Paul Brook

trans-array.c (gfc_trans_allocate_array_storage, [...]): For functions...

	* trans-array.c (gfc_trans_allocate_array_storage,
	gfc_trans_allocate_temp_array, gfc_add_loop_ss_code,
	gfc_conv_loop_setup):
	For functions, if the shape of the result is not known
	in compile-time, generate an empty array descriptor for
	the result and let the callee to allocate the memory.
	(gfc_trans_dummy_array_bias): Do nothing for pointers.
	(gfc_conv_expr_descriptor): Use function return values directly.
	* trans-expr.c (gfc_conv_function_call): Always add byref call
	insn to pre chain.
	(gfc_trans_pointer_assignment): Add comments.
	(gfc_trans_arrayfunc_assign): Don't chain on expression.
testsuite/
	* gfortran.dg/ret_array_1.f90: New test.
	* gfortran.dg/ret_pointer_1.f90: New test.

From-SVN: r85642
parent 160ff372
2004-08-06 Victor Leikehman <lei@il.ibm.com>
Paul Brook <paul@codesourcery.com>
* trans-array.c (gfc_trans_allocate_array_storage,
gfc_trans_allocate_temp_array, gfc_add_loop_ss_code,
gfc_conv_loop_setup): For functions, if the shape of the result
is not known in compile-time, generate an empty array descriptor for
the result and let the callee to allocate the memory.
(gfc_trans_dummy_array_bias): Do nothing for pointers.
(gfc_conv_expr_descriptor): Use function return values directly.
* trans-expr.c (gfc_conv_function_call): Always add byref call
insn to pre chain.
(gfc_trans_pointer_assignment): Add comments.
(gfc_trans_arrayfunc_assign): Don't chain on expression.
2004-08-01 Roger Sayle <roger@eyesopen.com> 2004-08-01 Roger Sayle <roger@eyesopen.com>
* options.c (gfc_init_options): Don't warn about the use GNU * options.c (gfc_init_options): Don't warn about the use GNU
......
...@@ -1171,16 +1171,20 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, ...@@ -1171,16 +1171,20 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
TREE_SIDE_EFFECTS (se->expr) = 1; TREE_SIDE_EFFECTS (se->expr) = 1;
#endif #endif
if (byref && !se->direct_byref) if (byref)
{ {
/* Add the function call to the pre chain. There is no expression. */
gfc_add_expr_to_block (&se->pre, se->expr); gfc_add_expr_to_block (&se->pre, se->expr);
se->expr = NULL_TREE;
if (!se->direct_byref)
{
if (sym->result->attr.dimension) if (sym->result->attr.dimension)
{ {
if (flag_bounds_check) if (flag_bounds_check)
{ {
/* Check the data pointer hasn't been modified. This would happen /* Check the data pointer hasn't been modified. This would
in a function returning a pointer. */ happen in a function returning a pointer. */
tmp = gfc_conv_descriptor_data (info->descriptor); tmp = gfc_conv_descriptor_data (info->descriptor);
tmp = build (NE_EXPR, boolean_type_node, tmp, info->data); tmp = build (NE_EXPR, boolean_type_node, tmp, info->data);
gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre); gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
...@@ -1195,6 +1199,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, ...@@ -1195,6 +1199,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
else else
abort (); abort ();
} }
}
} }
...@@ -1637,6 +1642,8 @@ gfc_trans_pointer_assign (gfc_code * code) ...@@ -1637,6 +1642,8 @@ gfc_trans_pointer_assign (gfc_code * code)
} }
/* Generate code for a pointer assignment. */
tree tree
gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
{ {
...@@ -1654,6 +1661,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) ...@@ -1654,6 +1661,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
rss = gfc_walk_expr (expr2); rss = gfc_walk_expr (expr2);
if (lss == gfc_ss_terminator) if (lss == gfc_ss_terminator)
{ {
/* Scalar pointers. */
lse.want_pointer = 1; lse.want_pointer = 1;
gfc_conv_expr (&lse, expr1); gfc_conv_expr (&lse, expr1);
assert (rss == gfc_ss_terminator); assert (rss == gfc_ss_terminator);
...@@ -1669,6 +1677,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) ...@@ -1669,6 +1677,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
} }
else else
{ {
/* Array pointer. */
gfc_conv_expr_descriptor (&lse, expr1, lss); gfc_conv_expr_descriptor (&lse, expr1, lss);
/* Implement Nullify. */ /* Implement Nullify. */
if (expr2->expr_type == EXPR_NULL) if (expr2->expr_type == EXPR_NULL)
...@@ -1796,7 +1805,6 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2) ...@@ -1796,7 +1805,6 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
se.ss = gfc_walk_expr (expr2); se.ss = gfc_walk_expr (expr2);
assert (se.ss != gfc_ss_terminator); assert (se.ss != gfc_ss_terminator);
gfc_conv_function_expr (&se, expr2); gfc_conv_function_expr (&se, expr2);
gfc_add_expr_to_block (&se.pre, se.expr);
gfc_add_block_to_block (&se.pre, &se.post); gfc_add_block_to_block (&se.pre, &se.post);
return gfc_finish_block (&se.pre); return gfc_finish_block (&se.pre);
......
2004-08-06 Paul Brook <paul@codesourcery.com>
* gfortran.dg/ret_array_1.f90: New test.
* gfortran.dg/ret_pointer_1.f90: New test.
2004-08-06 Richard Sandiford <rsandifo@redhat.com> 2004-08-06 Richard Sandiford <rsandifo@redhat.com>
* gcc.dg/missing-field-init-[12].c: New tests. * gcc.dg/missing-field-init-[12].c: New tests.
......
! { dg-do run }
! Test functions returning arrays of indeterminate size.
program ret_array_1
integer, dimension(:, :), allocatable :: a
integer, dimension(2) :: b
allocate (a(2, 3))
a = reshape ((/1, 2, 3, 4, 5, 6/), (/2, 3/))
! Using the return value as an actual argument
b = 0;
b = sum (transpose (a), 1);
if (any (b .ne. (/9, 12/))) call abort ()
! Using the return value in an expression
b = 0;
b = sum (transpose (a) + 1, 1);
if (any (b .ne. (/12, 15/))) call abort ()
! Same again testing a user function
! TODO: enable these once this is implemented
! b = 0;
! b = sum (my_transpose (a), 1);
! if (any (b .ne. (/9, 12/))) call abort ()
!
! ! Using the return value in an expression
! b = 0;
! b = sum (my_transpose (a) + 1, 1);
! if (any (b .ne. (/12, 15/))) call abort ()
contains
subroutine test(x, n)
integer, dimension (:, :) :: x
integer n
if (any (shape (x) .ne. (/3, 2/))) call abort
if (any (x .ne. (n + reshape((/1, 4, 2, 5, 3, 6/), (/3, 2/))))) call abort
end subroutine
function my_transpose (x) result (r)
interface
pure function obfuscate (i)
integer obfuscate
integer, intent(in) :: i
end function
end interface
integer, dimension (:, :) :: x
integer, dimension (obfuscate(ubound(x, 2)), &
obfuscate(ubound(x, 1))) :: r
integer i
do i = 1, ubound(x, 1)
r(:, i) = x(i, :)
end do
end function
end program
pure function obfuscate (i)
integer obfuscate
integer, intent(in) :: i
obfuscate = i
end function
! PR16898 : XFAILed because of problems with aliasing of array descriptors.
! Basically a and r get put in different alias sets, then the rtl optimizars
! wreak havoc when foo is inlined.
! { dg-do run { xfail *-*-* } }
! Test functions returning array pointers
program ret_pointer_1
integer, pointer, dimension(:) :: a
integer, target, dimension(2) :: b
integer, pointer, dimension (:) :: p
a => NULL()
a => foo()
p => b
if (.not. associated (a, p)) call abort
contains
subroutine bar(p)
integer, pointer, dimension(:) :: p
end subroutine
function foo() result(r)
integer, pointer, dimension(:) :: r
r => b
end function
end program
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment