Fix PR fortran/93671; ICE in reffing coarray alloc. comps.
authorAndre Vehreschild <vehre@gcc.gnu.org>
Thu, 13 Aug 2020 14:06:31 +0000 (16:06 +0200)
committerAndre Vehreschild <vehre@gcc.gnu.org>
Thu, 13 Aug 2020 14:06:31 +0000 (16:06 +0200)
Fix an ICE when in a coarray an allocatable component had another allocatable
component.

gcc/fortran/ChangeLog:

2020-08-10  Andre Vehreschild  <vehre@gcc.gnu.org>

PR fortran/93671
* trans-array.c (structure_alloc_comps): Keep caf-mode when applying to
components; get the caf_token correctly for allocated scalar components.

gcc/testsuite/ChangeLog:

2020-08-10  Andre Vehreschild  <vehre@gcc.gnu.org>

PR fortran/93671
* gfortran.dg/coarray/pr93671.f90: New test.

gcc/fortran/trans-array.c
gcc/testsuite/gfortran.dg/coarray/pr93671.f90 [new file with mode: 0644]

index 8f93b43bafbeac3618b2e2d7eceecfd90d82e027..7a1b2fc74c988d969a95aeda4fade987495340a9 100644 (file)
@@ -8627,14 +8627,13 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
 
       vref = gfc_build_array_ref (var, index, NULL);
 
-      if ((purpose == COPY_ALLOC_COMP || purpose == COPY_ONLY_ALLOC_COMP)
-         && !caf_enabled (caf_mode))
+      if (purpose == COPY_ALLOC_COMP || purpose == COPY_ONLY_ALLOC_COMP)
        {
          tmp = build_fold_indirect_ref_loc (input_location,
                                             gfc_conv_array_data (dest));
          dref = gfc_build_array_ref (tmp, index, NULL);
          tmp = structure_alloc_comps (der_type, vref, dref, rank,
-                                      COPY_ALLOC_COMP, 0, args);
+                                      COPY_ALLOC_COMP, caf_mode, args);
        }
       else
        tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose,
@@ -9375,12 +9374,21 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
              else if (flag_coarray == GFC_FCOARRAY_LIB
                       && caf_in_coarray (caf_mode))
                {
-                 tree dst_tok = c->as ? gfc_conv_descriptor_token (dcmp)
-                                      : fold_build3_loc (input_location,
-                                                         COMPONENT_REF,
-                                                         pvoid_type_node, dest,
-                                                         c->caf_token,
-                                                         NULL_TREE);
+                 tree dst_tok;
+                 if (c->as)
+                   dst_tok = gfc_conv_descriptor_token (dcmp);
+                 else
+                   {
+                     /* For a scalar allocatable component the caf_token is
+                        the next component.  */
+                     if (!c->caf_token)
+                         c->caf_token = c->next->backend_decl;
+                     dst_tok = fold_build3_loc (input_location,
+                                                COMPONENT_REF,
+                                                pvoid_type_node, dest,
+                                                c->caf_token,
+                                                NULL_TREE);
+                   }
                  tmp = duplicate_allocatable_coarray (dcmp, dst_tok, comp,
                                                       ctype, rank);
                }
diff --git a/gcc/testsuite/gfortran.dg/coarray/pr93671.f90 b/gcc/testsuite/gfortran.dg/coarray/pr93671.f90
new file mode 100644 (file)
index 0000000..8d26ff8
--- /dev/null
@@ -0,0 +1,24 @@
+! { dg-do run }
+
+! PR/fortran 93671 - ICE on intrinsic assignment to allocatable derived-type
+!                    component of coarray
+
+  type flux_planes
+    integer, allocatable :: normals
+  end type
+
+  type package
+    type(flux_planes) surface_fluxes(1)
+  end type
+
+  type(package) mail[*], halo_data
+
+  halo_data%surface_fluxes(1)%normals = 1
+  mail = halo_data
+  
+  if (any(size(mail%surface_fluxes) /= [1]) .OR. &
+          mail%surface_fluxes(1)%normals /= 1) then
+    stop 1
+  end if
+end
+