These patches change the descriptor initialization code in
gfc_conv_expr_descriptor introduced by the recent scalarizer patchset at
http://gcc.gnu.org/ml/fortran/2011-09/msg00056.html.
It was supposing (just like the code it was replacing) that coarrays were
always full, but a subobject of a coarray is also a coarray (if 
non-allocatable, non-pointer).
Thus, if `a' is a coarray of rank 2; `a', `a(1,:)' and `a(1,2)' are all valid
coarrays.
Because of the two latter ones, we have to distinguish between the full array
rank (2 in the three cases above), and the partial reference rank (respectively
2, 1, 0).
As a result:
 - in patch 4, we use loop.dimen (partial rank) instead of ndim (full rank) for
   accessing loop and descriptor elements.
 - in patch 3, we count codimensions from 0 and add to it either ndim or
   loop.dimen depending on whether we access array ref's elements or loop
   elements.
Patches 1 and 2 are preliminary changes.

OK?

2011-10-06  Mikael Morin  <mikael.mo...@sfr.fr>

        * trans-array.c (gfc_conv_expr_descriptor): Move ndim initialization
        earlier.
diff --git a/trans-array.c b/trans-array.c
index 5144398..1db2186 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -5962,6 +5962,8 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
       tree to;
       tree base;
 
+      ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
+
       if (se->want_coarray)
 	{
 	  codim = gfc_get_corank (expr);
@@ -6034,7 +6036,6 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
       else
 	base = NULL_TREE;
 
-      ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
       for (n = 0; n < ndim; n++)
 	{
 	  stride = gfc_conv_array_stride (desc, n);
2011-10-06  Mikael Morin  <mikael.mo...@sfr.fr>

        * trans-array.c (gfc_conv_expr_descriptor): Save some horizontal space.
diff --git a/trans-array.c b/trans-array.c
index 1db2186..034486d 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -5966,16 +5966,18 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 
       if (se->want_coarray)
 	{
+	  gfc_array_ref *ar = &info->ref->u.ar;
+
 	  codim = gfc_get_corank (expr);
 	  for (n = ss->data.info.dimen; n < ss->data.info.dimen + codim - 1;
 	       n++)
 	    {
 	      /* Make sure we are not lost somehow.  */
-	      gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_THIS_IMAGE);
+	      gcc_assert (ar->dimen_type[n] == DIMEN_THIS_IMAGE);
 
 	      /* Make sure the call to gfc_conv_section_startstride won't 
 	         generate unnecessary code to calculate stride.  */
-	      gcc_assert (info->ref->u.ar.stride[n] == NULL);
+	      gcc_assert (ar->stride[n] == NULL);
 
 	      gfc_conv_section_startstride (&loop, ss, n);
 	      loop.from[n] = info->start[n];
@@ -5983,7 +5985,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 	    }
 
 	  gcc_assert (n == ss->data.info.dimen + codim - 1);
-	  evaluate_bound (&loop.pre, info->start, info->ref->u.ar.start,
+	  evaluate_bound (&loop.pre, info->start, ar->start,
 			  info->descriptor, n, true);
 	  loop.from[n] = info->start[n];
 	}
2011-10-06  Mikael Morin  <mikael.mo...@sfr.fr>

        PR fortran/50420
        * trans-array.c (gfc_conv_expr_descriptor): Count codimensions starting
        from zero, and add then the relevant offset (either ndim or loop.dimen)
        depending on context.
diff --git a/trans-array.c b/trans-array.c
index 034486d..57534e0 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -5969,25 +5969,24 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 	  gfc_array_ref *ar = &info->ref->u.ar;
 
 	  codim = gfc_get_corank (expr);
-	  for (n = ss->data.info.dimen; n < ss->data.info.dimen + codim - 1;
-	       n++)
+	  for (n = 0; n < codim - 1; n++)
 	    {
 	      /* Make sure we are not lost somehow.  */
-	      gcc_assert (ar->dimen_type[n] == DIMEN_THIS_IMAGE);
+	      gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE);
 
 	      /* Make sure the call to gfc_conv_section_startstride won't 
 	         generate unnecessary code to calculate stride.  */
-	      gcc_assert (ar->stride[n] == NULL);
+	      gcc_assert (ar->stride[n + ndim] == NULL);
 
-	      gfc_conv_section_startstride (&loop, ss, n);
-	      loop.from[n] = info->start[n];
-	      loop.to[n]   = info->end[n];
+	      gfc_conv_section_startstride (&loop, ss, n + ndim);
+	      loop.from[n + loop.dimen] = info->start[n + ndim];
+	      loop.to[n + loop.dimen]   = info->end[n + ndim];
 	    }
 
-	  gcc_assert (n == ss->data.info.dimen + codim - 1);
+	  gcc_assert (n == codim - 1);
 	  evaluate_bound (&loop.pre, info->start, ar->start,
-			  info->descriptor, n, true);
-	  loop.from[n] = info->start[n];
+			  info->descriptor, n + ndim, true);
+	  loop.from[n + loop.dimen] = info->start[n + ndim];
 	}
       else
 	codim = 0;
2011-10-06  Mikael Morin  <mikael.mo...@sfr.fr>

        PR fortran/50420
        * trans-array.c (gfc_conv_expr_descriptor): Use loop.dimen instead of
        ndim for the descriptor's rank.
diff --git a/trans-array.c b/trans-array.c
index 57534e0..605b356 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -6138,13 +6138,13 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 					  gfc_rank_cst[dim], stride);
 	}
 
-      for (n = ndim; n < ndim + codim; n++)
+      for (n = loop.dimen; n < loop.dimen + codim; n++)
 	{
 	  from = loop.from[n];
 	  to = loop.to[n];
 	  gfc_conv_descriptor_lbound_set (&loop.pre, parm,
 					  gfc_rank_cst[n], from);
-	  if (n < ndim + codim - 1)
+	  if (n < loop.dimen + codim - 1)
 	    gfc_conv_descriptor_ubound_set (&loop.pre, parm,
 					    gfc_rank_cst[n], to);
 	}

Reply via email to