re PR fortran/91726 (ICE in gfc_conv_array_ref, at fortran/trans-array.c:3612)
authorPaul Thomas <pault@gcc.gnu.org>
Sun, 29 Sep 2019 10:12:42 +0000 (10:12 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sun, 29 Sep 2019 10:12:42 +0000 (10:12 +0000)
2019-09-29  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/91726
* resolve.c (gfc_expr_to_initialize): Bail out with a copy of
the original expression if the array ref is a scalar and the
array_spec has corank.
* trans-array.c (gfc_conv_array_ref): Such expressions are OK
even if the array ref codimen is zero.
* trans-expr.c (gfc_get_class_from_expr): New function taken
from gfc_get_vptr_from_expr.
(gfc_get_vptr_from_expr): Call new function.
* trans-stmt.c (trans_associate_var): If one of these is a
target expression, extract the class expression from the target
and copy its fields to a new target variable.
* trans.h : Add prototype for gfc_get_class_from_expr.

2019-09-29  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/91726
* gfortran.dg/coarray_poly_9.f90 : New test.

From-SVN: r276269

gcc/fortran/ChangeLog
gcc/fortran/resolve.c
gcc/fortran/trans-array.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-stmt.c
gcc/fortran/trans.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/coarray_poly_9.f90 [new file with mode: 0644]

index 0b870066b6602f44e8d9f5e8d25d2879d65ee729..8fc562531c91515391ccd4d9826f2540645dc3f1 100644 (file)
@@ -1,3 +1,19 @@
+2019-09-29  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/91726
+       * resolve.c (gfc_expr_to_initialize): Bail out with a copy of
+       the original expression if the array ref is a scalar and the
+       array_spec has corank.
+       * trans-array.c (gfc_conv_array_ref): Such expressions are OK
+       even if the array ref codimen is zero.
+       * trans-expr.c (gfc_get_class_from_expr): New function taken
+       from gfc_get_vptr_from_expr.
+       (gfc_get_vptr_from_expr): Call new function.
+       * trans-stmt.c (trans_associate_var): If one of these is a
+       target expression, extract the class expression from the target
+       and copy its fields to a new target variable.
+       * trans.h : Add prototype for gfc_get_class_from_expr.
+
 2019-09-28  Jerry DeLisle  <jvdelisle@gcc.ngu.org>
 
        PR fortran/91802
@@ -14,7 +30,7 @@
        PR fortran/91864
        * gcc/fortran/io.c (match_io_element): An inquiry parameter cannot be
        read into.
-       * gcc/fortran/match.c (gfc_match_allocate): An inquiry parameter 
+       * gcc/fortran/match.c (gfc_match_allocate): An inquiry parameter
        can be neither an allocate-object nor stat variable.
        (gfc_match_deallocate): An inquiry parameter cannot be deallocated.
 
index f1de7dd76c611760332b86f6e8eeaab2403b144e..e8d056625140a6c75c2721cb21ca959286984a39 100644 (file)
@@ -7433,6 +7433,10 @@ gfc_expr_to_initialize (gfc_expr *e)
   for (ref = result->ref; ref; ref = ref->next)
     if (ref->type == REF_ARRAY && ref->next == NULL)
       {
+       if (ref->u.ar.dimen == 0
+           && ref->u.ar.as && ref->u.ar.as->corank)
+         return result;
+
        ref->u.ar.type = AR_FULL;
 
        for (i = 0; i < ref->u.ar.dimen; i++)
index 07c4d7e671fd417c988e74d447f2201cbe9daaf0..437892a6abf21eb6f46146a71b4c34b48a7df352 100644 (file)
@@ -3609,7 +3609,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
 
   if (ar->dimen == 0)
     {
-      gcc_assert (ar->codimen || sym->attr.select_rank_temporary);
+      gcc_assert (ar->codimen || sym->attr.select_rank_temporary
+                 || (ar->as && ar->as->corank));
 
       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
        se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
index 2adc112bcecda6f46079c0912f11264216c3f415..61db4e39210c88f34d16ba2a08e3e19dfc5c70ec 100644 (file)
@@ -472,11 +472,11 @@ gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
 }
 
 
-/* Obtain the vptr of the last class reference in an expression.
+/* Obtain the last class reference in an expression.
    Return NULL_TREE if no class reference is found.  */
 
 tree
-gfc_get_vptr_from_expr (tree expr)
+gfc_get_class_from_expr (tree expr)
 {
   tree tmp;
   tree type;
@@ -487,7 +487,7 @@ gfc_get_vptr_from_expr (tree expr)
       while (type)
        {
          if (GFC_CLASS_TYPE_P (type))
-           return gfc_class_vptr_get (tmp);
+           return tmp;
          if (type != TYPE_CANONICAL (type))
            type = TYPE_CANONICAL (type);
          else
@@ -501,6 +501,23 @@ gfc_get_vptr_from_expr (tree expr)
     tmp = build_fold_indirect_ref_loc (input_location, tmp);
 
   if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
+    return tmp;
+
+  return NULL_TREE;
+}
+
+
+/* Obtain the vptr of the last class reference in an expression.
+   Return NULL_TREE if no class reference is found.  */
+
+tree
+gfc_get_vptr_from_expr (tree expr)
+{
+  tree tmp;
+
+  tmp = gfc_get_class_from_expr (expr);
+
+  if (tmp != NULL_TREE)
     return gfc_class_vptr_get (tmp);
 
   return NULL_TREE;
index 856a171abf4761e8824eb8059f30831c70ad109c..e3ea38a9aa159d8fe37123551037236e195fb1a8 100644 (file)
@@ -2099,7 +2099,43 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
        }
       else
        {
+         tree ctree = gfc_get_class_from_expr (se.expr);
          tmp = TREE_TYPE (sym->backend_decl);
+
+         /* Coarray scalar component expressions can emerge from
+            the front end as array elements of the _data field.  */
+         if (sym->ts.type == BT_CLASS
+             && e->ts.type == BT_CLASS && e->rank == 0
+             && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)) && ctree)
+           {
+             tree stmp;
+             tree dtmp;
+
+             se.expr = ctree;
+             dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
+             ctree = gfc_create_var (dtmp, "class");
+
+             stmp = gfc_class_data_get (se.expr);
+             gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)));
+
+             /* Set the fields of the target class variable.  */
+             stmp = gfc_conv_descriptor_data_get (stmp);
+             dtmp = gfc_class_data_get (ctree);
+             stmp = fold_convert (TREE_TYPE (dtmp), stmp);
+             gfc_add_modify (&se.pre, dtmp, stmp);
+             stmp = gfc_class_vptr_get (se.expr);
+             dtmp = gfc_class_vptr_get (ctree);
+             stmp = fold_convert (TREE_TYPE (dtmp), stmp);
+             gfc_add_modify (&se.pre, dtmp, stmp);
+             if (UNLIMITED_POLY (sym))
+               {
+                 stmp = gfc_class_len_get (se.expr);
+                 dtmp = gfc_class_len_get (ctree);
+                 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
+                 gfc_add_modify (&se.pre, dtmp, stmp);
+               }
+             se.expr = ctree;
+           }
          tmp = gfc_build_addr_expr (tmp, se.expr);
        }
 
index 84793dc1df03687d7c00c5c6bbdc178753be704e..6ebb71de15252d088ba84f1f3ca9d69b277f4c2e 100644 (file)
@@ -442,6 +442,7 @@ tree gfc_vptr_final_get (tree);
 tree gfc_vptr_deallocate_get (tree);
 void gfc_reset_vptr (stmtblock_t *, gfc_expr *);
 void gfc_reset_len (stmtblock_t *, gfc_expr *);
+tree gfc_get_class_from_expr (tree);
 tree gfc_get_vptr_from_expr (tree);
 tree gfc_get_class_array_ref (tree, tree, tree, bool);
 tree gfc_copy_class_to_class (tree, tree, tree, bool);
index d0d2cb084c56dcb082f10c27d59c1201b2346509..a23c7286a6d000a76dc666fbfe37c4d85bbbf54a 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-29  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/91726
+       * gfortran.dg/coarray_poly_9.f90 : New test.
+
 2019-09-29  Kewen Lin  <linkw@gcc.gnu.org>
 
        * gcc.target/powerpc/conv-vectorize-1.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_9.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_9.f90
new file mode 100644 (file)
index 0000000..ea2a942
--- /dev/null
@@ -0,0 +1,38 @@
+! { dg-do run }
+! { dg-options "-fcoarray=single" }
+!
+! Test the fix for PR91726.
+!
+! Contributed by Gerhardt Steinmetz  <gscfq@t-online.de>
+!
+module m
+   type s
+      class(*), allocatable :: a[:]    ! This ICEd
+   end type
+   type t
+      class(*), allocatable :: a(:)[:] ! This was OK
+   end type
+end
+
+  use m
+  call foo
+  call bar
+contains
+  subroutine foo
+    type (s) :: a
+    integer(4) :: i = 42_4
+    allocate (a%a[*], source = i)     ! This caused runtime segfaults
+    select type (z => a%a)            ! ditto
+      type is (integer(4))
+      if (z .ne. 42_4) stop 1
+    end select
+  end subroutine
+  subroutine bar                      ! Arrays always worked
+    type (t) :: a
+    allocate (a%a(3)[*], source = [1_4, 2_4, 3_4])
+    select type (z => a%a)
+      type is (integer(4))
+      if (any (z .ne. [1_4, 2_4, 3_4])) stop 2
+    end select
+  end subroutine
+end