This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] Fix PR 21912: handle negative steps in implied-do-loopin array constructor


The issue was that for an implied do-loop with a negative step value, say
'i=n,1,-1', the exit condition would be 'i > 1' instead of 'i < 1', because we
would always generate a GT_EXPR instead of checking the direction in which
we're going.

The fix is straightforward, but since I was touching that function, I slightly
restructured it to make it IMO more readable.

Bubblestrapped and tested.  OK for 4.0 and mainline?  I'll commit a testcase
alongside this.

- Tobi

2005-06-05  Tobias Schl"uter  <tobias.schlueter@physik.uni-muenchen.de>

	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.

? err
? linenum
? semantic.cache
Index: trans-array.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-array.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 trans-array.c
*** trans-array.c	31 May 2005 17:19:10 -0000	1.47
--- trans-array.c	5 Jun 2005 13:18:04 -0000
*************** gfc_trans_array_constructor_value (stmtb
*** 721,727 ****
  {
    tree tmp;
    stmtblock_t body;
-   tree loopbody;
    gfc_se se;
  
    for (; c; c = c->next)
--- 721,726 ----
*************** gfc_trans_array_constructor_value (stmtb
*** 842,854 ****
              }
  	}
  
!       /* The frontend should already have done any expansions.  */
!       if (c->iterator)
  	{
  	  tree end;
  	  tree step;
  	  tree loopvar;
  	  tree exit_label;
  
  	  loopbody = gfc_finish_block (&body);
  
--- 841,863 ----
              }
  	}
  
!       /* 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);
  
*************** gfc_trans_array_constructor_value (stmtb
*** 877,893 ****
  	  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);
  	  tmp = build1_v (GOTO_EXPR, exit_label);
  	  TREE_USED (exit_label) = 1;
! 	  tmp = build3_v (COND_EXPR, end, 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.  */
  	  tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
  	  gfc_add_modify_expr (&body, loopvar, tmp);
  
--- 886,910 ----
  	  exit_label = gfc_build_label_decl (NULL_TREE);
  	  gfc_start_block (&body);
  
! 	  /* 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, cond, tmp, build_empty_stmt ());
  	  gfc_add_expr_to_block (&body, tmp);
  
  	  /* The main loop body.  */
  	  gfc_add_expr_to_block (&body, loopbody);
  
! 	  /* Increase loop variable by step.  */
  	  tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
  	  gfc_add_modify_expr (&body, loopvar, tmp);
  
*************** gfc_trans_array_constructor_value (stmtb
*** 900,911 ****
  	  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);
- 	}
      }
  }
  
--- 917,922 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]