[committed] Fortran: fix bounds-checking errors for CLASS array dummies [PR104908]

Message ID trinity-0f7657d9-aefb-45ca-9961-7904e22a78b5-1706375210555@3c-app-gmx-bap50
State Accepted
Headers
Series [committed] Fortran: fix bounds-checking errors for CLASS array dummies [PR104908] |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Harald Anlauf Jan. 27, 2024, 5:06 p.m. UTC
  Dear all,

commit r11-1235 for pr95331 addressed array bounds issues with
unlimited polymorphic array dummies, but caused regressions for
CLASS array dummies that lead to either wrong code with bounds-checking,
or an ICE.  The solution is simple: add a check whether the dummy
is unlimited polymorphic and otherwise restore the previous behavior.

The attached patch regtested fine on x86_64-pc-linux-gnu and was
OK'ed in the PR by Jerry.

Pushed as: r14-8471-gce61de1b8a1bb3

Since this is a 11/12/13/14 regression and appears safe otherwise,
I intend to backport as suitable, unless there are comments.

Thanks,
Harald
  

Patch

From ce61de1b8a1bb3a22118e900376f380768f2ba59 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Sat, 27 Jan 2024 17:41:43 +0100
Subject: [PATCH] Fortran: fix bounds-checking errors for CLASS array dummies
 [PR104908]

Commit r11-1235 addressed issues with bounds of unlimited polymorphic array
dummies.  However, using the descriptor from sym->backend_decl does break
the case of CLASS array dummies.  The obvious solution is to restrict the
fix to the unlimited polymorphic case, thus keeping the original descriptor
in the ordinary case.

gcc/fortran/ChangeLog:

	PR fortran/104908
	* trans-array.cc (gfc_conv_array_ref): Restrict use of transformed
	descriptor (sym->backend_decl) to the unlimited polymorphic case.

gcc/testsuite/ChangeLog:

	PR fortran/104908
	* gfortran.dg/pr104908.f90: New test.
---
 gcc/fortran/trans-array.cc             |  5 +++-
 gcc/testsuite/gfortran.dg/pr104908.f90 | 32 ++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pr104908.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 878a92aff18..1e0d698a949 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -4063,7 +4063,10 @@  gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
     }

   decl = se->expr;
-  if (IS_CLASS_ARRAY (sym) && sym->attr.dummy && ar->as->type != AS_DEFERRED)
+  if (UNLIMITED_POLY(sym)
+      && IS_CLASS_ARRAY (sym)
+      && sym->attr.dummy
+      && ar->as->type != AS_DEFERRED)
     decl = sym->backend_decl;

   cst_offset = offset = gfc_index_zero_node;
diff --git a/gcc/testsuite/gfortran.dg/pr104908.f90 b/gcc/testsuite/gfortran.dg/pr104908.f90
new file mode 100644
index 00000000000..c3a30b0003c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104908.f90
@@ -0,0 +1,32 @@ 
+! { dg-do compile }
+! { dg-additional-options "-fcheck=bounds -fdump-tree-original" }
+!
+! PR fortran/104908 - incorrect out-of-bounds runtime error
+
+program test
+  implicit none
+  type vec
+     integer :: x(3) = [2,4,6]
+  end type vec
+  type(vec) :: w(2)
+  call sub(w)
+contains
+  subroutine sub (v)
+    class(vec), intent(in) :: v(:)
+    integer :: k, q(3)
+    q = [ (v(1)%x(k), k = 1, 3) ]   ! <-- was failing here after r11-1235
+    print *, q
+  end
+end
+
+subroutine sub2 (zz)
+  implicit none
+  type vec
+     integer :: x(2,1)
+  end type vec
+  class(vec), intent(in) :: zz(:)   ! used to ICE after r11-1235
+  integer :: k
+  k = zz(1)%x(2,1)
+end
+
+! { dg-final { scan-tree-dump-times " above upper bound " 4 "original" } }
--
2.35.3