diff options
author | Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de> | 2005-06-05 20:03:47 +0200 |
---|---|---|
committer | Tobias Schlüter <tobi@gcc.gnu.org> | 2005-06-05 20:03:47 +0200 |
commit | 86403f0f329ea996b6323d4011d5da0111ab80d8 (patch) | |
tree | aca102703133fcb176eb7117ca293736b7291bf9 /gcc/fortran/trans-array.c | |
parent | 88a7beb769bd14c1affeb7c801842058e3071ab6 (diff) | |
download | gcc-86403f0f329ea996b6323d4011d5da0111ab80d8.zip gcc-86403f0f329ea996b6323d4011d5da0111ab80d8.tar.gz gcc-86403f0f329ea996b6323d4011d5da0111ab80d8.tar.bz2 |
re PR fortran/21912 (Wrong implied do-loop)
fortran/
PR fortran/21912
* trans-array.c (gfc_trans_array_constructor_value): Slightly reorder.
Generate correct exit condition in case of negative steps in
implied-do loops.
testsuite/
PR fortran/21912
* gfortran.dg/array_constructor_4.f90: New test.
From-SVN: r100630
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index fabbef9..3554107 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -721,7 +721,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, { tree tmp; stmtblock_t body; - tree loopbody; gfc_se se; for (; c; c = c->next) @@ -842,13 +841,23 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, } } - /* The frontend should already have done any expansions. */ - if (c->iterator) + /* The frontend should already have done any expansions possible + at compile-time. */ + if (!c->iterator) + { + /* Pass the code as is. */ + tmp = gfc_finish_block (&body); + gfc_add_expr_to_block (pblock, tmp); + } + else { + /* Build the implied do-loop. */ + tree cond; tree end; tree step; tree loopvar; tree exit_label; + tree loopbody; loopbody = gfc_finish_block (&body); @@ -877,17 +886,25 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, exit_label = gfc_build_label_decl (NULL_TREE); gfc_start_block (&body); - /* Generate the exit condition. */ - end = build2 (GT_EXPR, boolean_type_node, loopvar, end); + /* Generate the exit condition. Depending on the sign of + the step variable we have to generate the correct + comparison. */ + tmp = fold_build2 (GT_EXPR, boolean_type_node, step, + build_int_cst (TREE_TYPE (step), 0)); + cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, + build2 (GT_EXPR, boolean_type_node, + loopvar, end), + build2 (LT_EXPR, boolean_type_node, + loopvar, end)); tmp = build1_v (GOTO_EXPR, exit_label); TREE_USED (exit_label) = 1; - tmp = build3_v (COND_EXPR, end, tmp, build_empty_stmt ()); + tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ()); gfc_add_expr_to_block (&body, tmp); /* The main loop body. */ gfc_add_expr_to_block (&body, loopbody); - /* Increment the loop variable. */ + /* Increase loop variable by step. */ tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step); gfc_add_modify_expr (&body, loopvar, tmp); @@ -900,12 +917,6 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type, tmp = build1_v (LABEL_EXPR, exit_label); gfc_add_expr_to_block (pblock, tmp); } - else - { - /* Pass the code as is. */ - tmp = gfc_finish_block (&body); - gfc_add_expr_to_block (pblock, tmp); - } } } |