Dear all,

the attached obvious patch fixes the array check for class array valued
constructors and functions, and a latent NULL pointer dereference that
could occur later.

Regtested on x86_64-pc-linux-gnu.  OK for mainline / 15-backport?

Thanks,
Harald

From 5293a3447add8ad017e8cd6bdeb5d484b675dced Mon Sep 17 00:00:00 2001
From: Harald Anlauf <[email protected]>
Date: Sat, 7 Feb 2026 20:23:04 +0100
Subject: [PATCH] Fortran: fix check for class array valued constructors and
 functions [PR123961]

	PR fortran/123961

gcc/fortran/ChangeLog:

	* check.cc (array_check): Extend check to class array functions.
	* class.cc (gfc_add_class_array_ref): Fix NULL pointer dereference.

gcc/testsuite/ChangeLog:

	* gfortran.dg/class_array_24.f90: New test.
---
 gcc/fortran/check.cc                         |  3 +
 gcc/fortran/class.cc                         |  2 +-
 gcc/testsuite/gfortran.dg/class_array_24.f90 | 58 ++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/class_array_24.f90

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 6bba58e7d1c..4a4e1a8d21d 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -832,6 +832,9 @@ array_check (gfc_expr *e, int n)
   if (e->rank != 0 && e->ts.type != BT_PROCEDURE)
     return true;
 
+  if (gfc_is_class_array_function (e))
+    return true;
+
   gfc_error ("%qs argument of %qs intrinsic at %L must be an array",
 	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
 	     &e->where);
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 2798651c411..9c02b9bc81e 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -273,7 +273,7 @@ gfc_add_class_array_ref (gfc_expr *e)
   for (ref = e->ref; ref; ref = ref->next)
     if (!ref->next)
       break;
-  if (ref->type != REF_ARRAY)
+  if (ref && ref->type != REF_ARRAY)
     {
       ref->next = gfc_get_ref ();
       ref = ref->next;
diff --git a/gcc/testsuite/gfortran.dg/class_array_24.f90 b/gcc/testsuite/gfortran.dg/class_array_24.f90
new file mode 100644
index 00000000000..c6b1ec1aa9e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_array_24.f90
@@ -0,0 +1,58 @@
+! { dg-do run }
+! { dg-additional-options "-O2 -fdump-tree-optimized" }
+!
+! PR fortran/123961 - SIZE and class array valued constructors and functions
+
+module test_overload_m
+  implicit none
+
+  type :: foo_t
+  end type foo_t
+
+  interface foo_t
+     module procedure foo_t_0_
+     module procedure foo_t_1_
+     module procedure foo_c_0_
+     module procedure foo_c_1_
+  end interface foo_t
+
+contains
+
+  function foo_t_0_(i) result(foo)
+    integer, intent(in)      :: i
+    type(foo_t), allocatable :: foo
+    allocate (foo)
+  end function foo_t_0_
+
+  function foo_t_1_(i) result(foo)
+    integer, intent(in)      :: i(:)
+    type(foo_t), allocatable :: foo(:)
+
+    allocate (foo(size (i)))
+  end function foo_t_1_
+
+  function foo_c_0_(r) result(foo)
+    real, intent(in)          :: r
+    class(foo_t), allocatable :: foo
+    allocate (foo)
+  end function foo_c_0_
+
+  function foo_c_1_(r) result(foo)
+    real, intent(in)          :: r(:)
+    class(foo_t), allocatable :: foo(:)
+
+    allocate (foo(size (r)))
+  end function foo_c_1_
+
+end module test_overload_m
+
+program test_overload
+   use test_overload_m
+   implicit none
+
+   if (size (foo_t([1,2,3])) /= 3) stop 1   ! Optimized
+   if (size (foo_t([1.,2.])) /= 2) stop 2   ! Optimized
+
+end program test_overload
+
+! { dg-final { scan-tree-dump-not "_gfortran_error_stop_numeric" "optimized" } }
-- 
2.51.0

Reply via email to