https://gcc.gnu.org/g:d3c18b92c97b0fd477c7a43ab7af1ed88faec4ba

commit r14-11065-gd3c18b92c97b0fd477c7a43ab7af1ed88faec4ba
Author: Harald Anlauf <anl...@gmx.de>
Date:   Wed Nov 27 21:11:16 2024 +0100

    Fortran: fix crash with bounds check writing array section [PR117791]
    
            PR fortran/117791
    
    gcc/fortran/ChangeLog:
    
            * trans-io.cc (gfc_trans_transfer): When an array index depends on
            a function evaluation or an expression, do not use optimized array
            I/O of an array section and fall back to normal scalarization.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/bounds_check_array_io.f90: New test.
    
    (cherry picked from commit 2261a15c0715cbf5c129b66ee44fc1d3a9e36972)

Diff:
---
 gcc/fortran/trans-io.cc                            | 20 ++++++++++++++
 .../gfortran.dg/bounds_check_array_io.f90          | 31 ++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc
index 0c5a1714be6f..c7a50e8839c8 100644
--- a/gcc/fortran/trans-io.cc
+++ b/gcc/fortran/trans-io.cc
@@ -2633,6 +2633,26 @@ gfc_trans_transfer (gfc_code * code)
             || gfc_expr_attr (expr).pointer))
        goto scalarize;
 
+      /* With array-bounds checking enabled, force scalarization in some
+        situations, e.g., when an array index depends on a function
+        evaluation or an expression and possibly has side-effects.  */
+      if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
+         && ref
+         && ref->u.ar.type == AR_SECTION)
+       {
+         for (n = 0; n < ref->u.ar.dimen; n++)
+           if (ref->u.ar.dimen_type[n] == DIMEN_ELEMENT
+               && ref->u.ar.start[n])
+             {
+               switch (ref->u.ar.start[n]->expr_type)
+                 {
+                 case EXPR_FUNCTION:
+                 case EXPR_OP:
+                   goto scalarize;
+                 }
+             }
+       }
+
       if (!(gfc_bt_struct (expr->ts.type)
              || expr->ts.type == BT_CLASS)
            && ref && ref->next == NULL
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_array_io.f90 
b/gcc/testsuite/gfortran.dg/bounds_check_array_io.f90
new file mode 100644
index 000000000000..0cfc11742834
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_array_io.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+! { dg-additional-options "-fcheck=bounds -fdump-tree-original" }
+!
+! PR fortran/117791 - crash with bounds check writing array section
+! Contributed by Andreas van Hameren (hameren at ifj dot edu dot pl)
+
+program testprogram
+  implicit none
+  integer, parameter :: array(4,2)=reshape ([11,12,13,14 ,15,16,17,18], [4,2])
+  integer            :: i(3) = [45,51,0]
+
+  write(*,*) 'line 1:',array(:,          sort_2(i(1:2)) )
+  write(*,*) 'line 2:',array(:,      3 - sort_2(i(1:2)) )
+  write(*,*) 'line 3:',array(:, int (3 - sort_2(i(1:2))))
+
+contains
+
+  function sort_2(i) result(rslt)
+    integer,intent(in) :: i(2)
+    integer            :: rslt
+    if (i(1) <= i(2)) then
+       rslt = 1
+    else
+       rslt = 2
+    endif
+  end function
+
+end program 
+
+! { dg-final { scan-tree-dump-times "sort_2" 5 "original" } }
+! { dg-final { scan-tree-dump-not "_gfortran_transfer_array_write" "original" 
} }

Reply via email to