Fortran: Fix ICE due to elemental procedure pointers [PR98472].
authorPaul Thomas <pault@gcc.gnu.org>
Wed, 27 Jan 2021 09:12:16 +0000 (09:12 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Wed, 27 Jan 2021 09:12:54 +0000 (09:12 +0000)
2021-01-27  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/98472
* trans-array.c (gfc_conv_expr_descriptor): Include elemental
procedure pointers in the assert under the comment 'elemental
function' and eliminate the second, spurious assert.

gcc/testsuite/
PR fortran/98472
* gfortran.dg/elemental_function_5.f90 : New test.

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

index 4bd4db877bd0c33d3a0bfe8db42c7989b43bc3b1..c346183e1299aba8bf7d6ec078e00ba3ee67aae3 100644 (file)
@@ -7477,9 +7477,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
                         && expr->value.function.esym->attr.elemental)
                        || (expr->value.function.isym != NULL
                            && expr->value.function.isym->elemental)
+                       || (gfc_expr_attr (expr).proc_pointer
+                           && gfc_expr_attr (expr).elemental)
                        || gfc_inline_intrinsic_function_p (expr));
-         else
-           gcc_assert (ss_type == GFC_SS_INTRINSIC);
 
          need_tmp = 1;
          if (expr->ts.type == BT_CHARACTER
diff --git a/gcc/testsuite/gfortran.dg/elemental_function_5.f90 b/gcc/testsuite/gfortran.dg/elemental_function_5.f90
new file mode 100644 (file)
index 0000000..315ff91
--- /dev/null
@@ -0,0 +1,46 @@
+! { dg-do compile }
+!
+! Test the fix for PR98472.
+!
+! Contributed by Rui Coelho  <ruicoelhopedro@hotmail.com>
+!
+module a
+        type, abstract :: base
+        contains
+                procedure(elem_func), deferred, nopass :: add
+        end type base
+
+        type, extends(base) :: derived
+        contains
+                procedure, nopass :: add => add_derived
+        end type derived
+
+        abstract interface
+                elemental function elem_func(x, y) result(out)
+                        integer, intent(in) :: x, y
+                        integer :: out
+                end function elem_func
+        end interface
+
+contains
+        elemental function add_derived(x, y) result(out)
+                integer, intent(in) :: x, y
+                integer :: out
+                out = x + y
+        end function add_derived
+end module a
+
+program main
+        use a
+        call foo
+contains
+        subroutine foo
+               integer, dimension(:), allocatable :: vec
+               class(base), allocatable :: instance
+               allocate(derived :: instance)
+               allocate(vec, source=instance%add([1, 2], [1, 2])) ! ICE here
+               if (any (vec .ne. [2, 4])) stop 1
+        end
+end program main
+
+