Dear all,

the attached simple and obvious patch fixes an erroneous runtime check
with -fcheck=pointer when passing a non-associated proc-pointer to an
optional dummy.

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

Thanks,
Harald

From 8f9450505f8244d262f8b4ff274f113f99cdc7e2 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anl...@gmx.de>
Date: Fri, 18 Jul 2025 21:12:03 +0200
Subject: [PATCH] Fortran: fix bogus runtime error with optional procedure
 argument [PR121145]

	PR fortran/121145

gcc/fortran/ChangeLog:

	* trans-expr.cc (gfc_conv_procedure_call): Do not create pointer
	check for proc-pointer actual passed to optional dummy.

gcc/testsuite/ChangeLog:

	* gfortran.dg/pointer_check_15.f90: New test.
---
 gcc/fortran/trans-expr.cc                     |  3 +-
 .../gfortran.dg/pointer_check_15.f90          | 46 +++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pointer_check_15.f90

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 082987f9cb8..6fa52d0ffef 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -8159,7 +8159,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 		msg = xasprintf ("Pointer actual argument '%s' is not "
 				 "associated", e->symtree->n.sym->name);
 	      else if (attr.proc_pointer && !e->value.function.actual
-		       && (fsym == NULL || !fsym_attr.proc_pointer))
+		       && (fsym == NULL
+			   || (!fsym_attr.proc_pointer && !fsym_attr.optional)))
 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
 				 "associated", e->symtree->n.sym->name);
 	      else
diff --git a/gcc/testsuite/gfortran.dg/pointer_check_15.f90 b/gcc/testsuite/gfortran.dg/pointer_check_15.f90
new file mode 100644
index 00000000000..13c6820be0e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_check_15.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+! { dg-additional-options "-O -fcheck=pointer -fdump-tree-original" }
+!
+! PR fortran/121145
+! Erroneous runtime error: Proc-pointer actual argument 'ptr' is not associated
+!
+! Contributed by Federico Perini.
+
+module m
+  implicit none
+
+  abstract interface
+     subroutine fun(x)
+       real, intent(in) :: x
+     end subroutine fun
+  end interface   
+
+contains
+
+  subroutine with_fun(sub)
+    procedure(fun), optional :: sub
+    if (present(sub)) stop 1
+  end subroutine   
+
+  subroutine with_non_optional(sub)
+    procedure(fun) :: sub
+  end subroutine   
+
+end module m
+
+program p
+  use m
+  implicit none
+
+  procedure(fun), pointer :: ptr1 => null()
+  procedure(fun), pointer :: ptr2 => null()
+  
+  call with_fun()
+  call with_fun(sub=ptr1)               ! no runtime check here
+
+  if (associated (ptr2)) then
+     call with_non_optional(sub=ptr2)   ! runtime check here
+  end if
+end  
+
+! { dg-final { scan-tree-dump-times "Proc-pointer actual argument .'ptr2.'" 1 "original" } }
-- 
2.43.0

Reply via email to