diff options
Diffstat (limited to 'gcc/fortran')
| -rw-r--r-- | gcc/fortran/ChangeLog | 10 | ||||
| -rw-r--r-- | gcc/fortran/trans-intrinsic.c | 32 |
2 files changed, 31 insertions, 11 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d0cbd0a8af7..e3876fc3ab0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2007-06-24 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/32298 + PR fortran/31726 + * trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Calculate + the offset between the loop counter and the position as + defined. Add the offset within the loop so that the mask acts + correctly. Do not advance the location on the basis that it + is zero. + 2007-06-22 Daniel Franke <franke.daniel@gmail.com> PR fortran/31473 diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index d1c371092fb..874b1081de6 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -1928,6 +1928,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op) tree tmp; tree elsetmp; tree ifbody; + tree offset; gfc_loopinfo loop; gfc_actual_arglist *actual; gfc_ss *arrayss; @@ -1947,6 +1948,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op) /* Initialize the result. */ pos = gfc_create_var (gfc_array_index_type, "pos"); + offset = gfc_create_var (gfc_array_index_type, "offset"); type = gfc_typenode_for_spec (&expr->ts); /* Walk the arguments. */ @@ -2045,15 +2047,28 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op) /* Assign the value to the limit... */ gfc_add_modify_expr (&ifblock, limit, arrayse.expr); - /* Remember where we are. */ - gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]); + /* Remember where we are. An offset must be added to the loop + counter to obtain the required position. */ + if (loop.temp_dim) + tmp = build_int_cst (gfc_array_index_type, 1); + else + tmp =fold_build2 (MINUS_EXPR, gfc_array_index_type, + gfc_index_one_node, loop.from[0]); + gfc_add_modify_expr (&block, offset, tmp); + + tmp = build2 (PLUS_EXPR, TREE_TYPE (pos), + loop.loopvar[0], offset); + gfc_add_modify_expr (&ifblock, pos, tmp); ifbody = gfc_finish_block (&ifblock); - /* If it is a more extreme value or pos is still zero. */ + /* If it is a more extreme value or pos is still zero and the value + equal to the limit. */ + tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, + build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node), + build2 (EQ_EXPR, boolean_type_node, arrayse.expr, limit)); tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, - build2 (op, boolean_type_node, arrayse.expr, limit), - build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node)); + build2 (op, boolean_type_node, arrayse.expr, limit), tmp); tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ()); gfc_add_expr_to_block (&block, tmp); @@ -2098,12 +2113,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op) } gfc_cleanup_loop (&loop); - /* Return a value in the range 1..SIZE(array). */ - tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0], - gfc_index_one_node); - tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp); - /* And convert to the required type. */ - se->expr = convert (type, tmp); + se->expr = convert (type, pos); } static void |

