[fortran] Fix PR 86837, wrong code regression in implied do loop in i/o
diff mbox series

Message ID a03e716b-ca9e-ff45-c49f-327c31c2f093@tkoenig.net
State New
Headers show
Series
  • [fortran] Fix PR 86837, wrong code regression in implied do loop in i/o
Related show

Commit Message

Thomas König Aug. 23, 2018, 8:12 p.m. UTC
Hello world,

this patch fixes a regression by correctly checking that
the innner start, step or end values of an implied do
loop do not depend on an outer loop variable.

The check was actually done before, but gfc_check_dependency
wasn't finding all relevant cases.

Regression-tested. OK for trunk and 8.x?

Regards

	Thomas

2018-08-23  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/86837
	* frontend-passes.c (var_in_expr_callback): New function.
	(var_in_expr): New function.
	(traverse_io_block): Use var_in_expr instead of
	gfc_check_dependency for checking if the variable depends on the
	previous interators.

2018-08-23  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/86837
	* gfortran.dg/implied_do_io_6.f90: New test.

Comments

Jerry DeLisle Aug. 24, 2018, 2:35 a.m. UTC | #1
On 08/23/2018 01:12 PM, Thomas König wrote:
> Hello world,
> 
> this patch fixes a regression by correctly checking that
> the innner start, step or end values of an implied do
> loop do not depend on an outer loop variable.
> 
> The check was actually done before, but gfc_check_dependency
> wasn't finding all relevant cases.
> 
> Regression-tested. OK for trunk and 8.x?
> 
> Regards
> 
>      Thomas
> 

Very OK Thomas.

Thanks for patch.

Jerry

Patch
diff mbox series

Index: frontend-passes.c
===================================================================
--- frontend-passes.c	(Revision 263752)
+++ frontend-passes.c	(Arbeitskopie)
@@ -1104,6 +1104,31 @@  convert_elseif (gfc_code **c, int *walk_subtrees A
   return 0;
 }
 
+/* Callback function to var_in_expr - return true if expr1 and
+   expr2 are identical variables. */
+static int
+var_in_expr_callback (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
+		      void *data)
+{
+  gfc_expr *expr1 = (gfc_expr *) data;
+  gfc_expr *expr2 = *e;
+
+  if (expr2->expr_type != EXPR_VARIABLE)
+    return 0;
+
+  return expr1->symtree->n.sym == expr2->symtree->n.sym;
+}
+
+/* Return true if expr1 is found in expr2. */
+
+static bool
+var_in_expr (gfc_expr *expr1, gfc_expr *expr2)
+{
+  gcc_assert (expr1->expr_type == EXPR_VARIABLE);
+
+  return gfc_expr_walker (&expr2, var_in_expr_callback, (void *) expr1);
+}
+
 struct do_stack
 {
   struct do_stack *prev;
@@ -1256,9 +1281,9 @@  traverse_io_block (gfc_code *code, bool *has_reach
 	  for (int j = i - 1; j < i; j++)
 	    {
 	      if (iters[j]
-		  && (gfc_check_dependency (var, iters[j]->start, true)
-		      || gfc_check_dependency (var, iters[j]->end, true)
-		      || gfc_check_dependency (var, iters[j]->step, true)))
+		  && (var_in_expr (var, iters[j]->start)
+		      || var_in_expr (var, iters[j]->end)
+		      || var_in_expr (var, iters[j]->step)))
 		  return false;
 	    }		  
 	}