Commit 5d63a35f by Paul Thomas

re PR fortran/36703 (ICE (segfault) in reduce_binary0 (arith.c:1778))

2009-02-13  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/36703
	PR fortran/36528
	* trans-expr.c (gfc_conv_function_val): Stabilize Cray-pointer
	function references to ensure that a valid expression is used.
	(gfc_conv_function_call): Pass Cray pointers to procedures.

2009-02-13  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/36528
	* gfortran.dg/cray_pointers_8.f90: New test.

	PR fortran/36703
	* gfortran.dg/cray_pointers_9.f90: New test.

From-SVN: r145196
parent 6b02d5f7
2009-03-28 Paul Thomas <pault@gcc.gnu.org> 2009-03-28 Paul Thomas <pault@gcc.gnu.org>
PR fortran/38538
* trans-array.c (get_elemental_fcn_charlen): Remove.
(get_array_charlen): New function to replace previous.
2009-03-28 Paul Thomas <pault@gcc.gnu.org>
PR fortran/38765 PR fortran/38765
* parse.c (parse_derived): Do not break on finding pointer, * parse.c (parse_derived): Do not break on finding pointer,
allocatable or private components. allocatable or private components.
......
...@@ -4703,47 +4703,102 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset, ...@@ -4703,47 +4703,102 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
} }
/* gfc_conv_expr_descriptor needs the character length of elemental /* gfc_conv_expr_descriptor needs the string length an expression
functions before the function is called so that the size of the so that the size of the temporary can be obtained. This is done
temporary can be obtained. The only way to do this is to convert by adding up the string lengths of all the elements in the
the expression, mapping onto the actual arguments. */ expression. Function with non-constant expressions have their
string lengths mapped onto the actual arguments using the
interface mapping machinery in trans-expr.c. */
static void static void
get_elemental_fcn_charlen (gfc_expr *expr, gfc_se *se) get_array_charlen (gfc_expr *expr, gfc_se *se)
{ {
gfc_interface_mapping mapping; gfc_interface_mapping mapping;
gfc_formal_arglist *formal; gfc_formal_arglist *formal;
gfc_actual_arglist *arg; gfc_actual_arglist *arg;
gfc_se tse; gfc_se tse;
formal = expr->symtree->n.sym->formal; if (expr->ts.cl->length
arg = expr->value.function.actual; && gfc_is_constant_expr (expr->ts.cl->length))
gfc_init_interface_mapping (&mapping);
/* Set se = NULL in the calls to the interface mapping, to suppress any
backend stuff. */
for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
{ {
if (!arg->expr) if (!expr->ts.cl->backend_decl)
continue; gfc_conv_string_length (expr->ts.cl, expr, &se->pre);
if (formal->sym) return;
gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
} }
gfc_init_se (&tse, NULL); switch (expr->expr_type)
{
case EXPR_OP:
get_array_charlen (expr->value.op.op1, se);
/* For parentheses the expression ts.cl is identical. */
if (expr->value.op.op == INTRINSIC_PARENTHESES)
return;
expr->ts.cl->backend_decl =
gfc_create_var (gfc_charlen_type_node, "sln");
if (expr->value.op.op2)
{
get_array_charlen (expr->value.op.op2, se);
/* Add the string lengths and assign them to the expression
string length backend declaration. */
gfc_add_modify (&se->pre, expr->ts.cl->backend_decl,
fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
expr->value.op.op1->ts.cl->backend_decl,
expr->value.op.op2->ts.cl->backend_decl));
}
else
gfc_add_modify (&se->pre, expr->ts.cl->backend_decl,
expr->value.op.op1->ts.cl->backend_decl);
break;
case EXPR_FUNCTION:
if (expr->value.function.esym == NULL
|| expr->ts.cl->length->expr_type == EXPR_CONSTANT)
{
gfc_conv_string_length (expr->ts.cl, expr, &se->pre);
break;
}
/* Map expressions involving the dummy arguments onto the actual
argument expressions. */
gfc_init_interface_mapping (&mapping);
formal = expr->symtree->n.sym->formal;
arg = expr->value.function.actual;
/* Set se = NULL in the calls to the interface mapping, to suppress any
backend stuff. */
for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
{
if (!arg->expr)
continue;
if (formal->sym)
gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
}
/* Build the expression for the character length and convert it. */ gfc_init_se (&tse, NULL);
gfc_apply_interface_mapping (&mapping, &tse, expr->ts.cl->length);
gfc_add_block_to_block (&se->pre, &tse.pre); /* Build the expression for the character length and convert it. */
gfc_add_block_to_block (&se->post, &tse.post); gfc_apply_interface_mapping (&mapping, &tse, expr->ts.cl->length);
tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
tse.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tse.expr, gfc_add_block_to_block (&se->pre, &tse.pre);
build_int_cst (gfc_charlen_type_node, 0)); gfc_add_block_to_block (&se->post, &tse.post);
expr->ts.cl->backend_decl = tse.expr; tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
gfc_free_interface_mapping (&mapping); tse.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tse.expr,
build_int_cst (gfc_charlen_type_node, 0));
expr->ts.cl->backend_decl = tse.expr;
gfc_free_interface_mapping (&mapping);
break;
default:
gfc_conv_string_length (expr->ts.cl, expr, &se->pre);
break;
}
} }
/* Convert an array for passing as an actual argument. Expressions and /* Convert an array for passing as an actual argument. Expressions and
vector subscripts are evaluated and stored in a temporary, which is then vector subscripts are evaluated and stored in a temporary, which is then
passed. For whole arrays the descriptor is passed. For array sections passed. For whole arrays the descriptor is passed. For array sections
...@@ -4879,7 +4934,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) ...@@ -4879,7 +4934,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
need_tmp = 1; need_tmp = 1;
if (expr->ts.type == BT_CHARACTER if (expr->ts.type == BT_CHARACTER
&& expr->ts.cl->length->expr_type != EXPR_CONSTANT) && expr->ts.cl->length->expr_type != EXPR_CONSTANT)
get_elemental_fcn_charlen (expr, se); get_array_charlen (expr, se);
info = NULL; info = NULL;
} }
...@@ -4939,8 +4994,9 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) ...@@ -4939,8 +4994,9 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
loop.temp_ss->type = GFC_SS_TEMP; loop.temp_ss->type = GFC_SS_TEMP;
loop.temp_ss->next = gfc_ss_terminator; loop.temp_ss->next = gfc_ss_terminator;
if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl) if (expr->ts.type == BT_CHARACTER
gfc_conv_string_length (expr->ts.cl, expr, &se->pre); && !expr->ts.cl->backend_decl)
get_array_charlen (expr, se);
loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts); loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
......
2009-03-28 Paul Thomas <pault@gcc.gnu.org
PR fortran/38538
* gfortran.dg/char_result_13.f90: New test.
2009-03-28 Paul Thomas <pault@gcc.gnu.org> 2009-03-28 Paul Thomas <pault@gcc.gnu.org>
PR fortran/38765 PR fortran/38765
......
! { dg-do run }
! Tests the fix for PR38538, where the character length for the
! argument of 'func' was not calculated.
!
! Contributed by Vivek Rao <vivekrao4@yahoo.com>
!
module abc
implicit none
contains
subroutine xmain (i, j)
integer i, j
call foo (func ("_"//bar (i)//"x"//bar (j)//"x"), "_abcxabx") ! original was elemental
call foo (nfunc("_"//bar (j)//"x"//bar (i)//"x"), "_abxabcx")
end subroutine xmain
!
function bar (i) result(yy)
integer i, j, k
character (len = i) :: yy(2)
do j = 1, size (yy, 1)
do k = 1, i
yy(j)(k:k) = char (96+k)
end do
end do
end function bar
!
elemental function func (yy) result(xy)
character (len = *), intent(in) :: yy
character (len = len (yy)) :: xy
xy = yy
end function func
!
function nfunc (yy) result(xy)
character (len = *), intent(in) :: yy(:)
character (len = len (yy)) :: xy(size (yy))
xy = yy
end function nfunc
!
subroutine foo(cc, teststr)
character (len=*), intent(in) :: cc(:)
character (len=*), intent(in) :: teststr
if (any (cc .ne. teststr)) call abort
end subroutine foo
end module abc
use abc
call xmain(3, 2)
end
! { dg-final { cleanup-modules "abc" } }
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