Dear All,

my fix for pr71565 introduced a regression for variable definition
context checks when the selector was not a dummy variable.
The reason was that I attempted to prevent a false-negative
for one of the tests in the testcase in a too naive way while
not fully walking through an association list.  The attached
patch remedies that.

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

Thanks,
Harald

From 046487e254d83ce7fa89926cf8417a3c413d3656 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <[email protected]>
Date: Mon, 22 Dec 2025 21:05:29 +0100
Subject: [PATCH] Fortran: fix variable definition context checks for SELECT
 TYPE [PR123253]

Commit r16-6300 introduced a regression when checking the variable
definition context of SELECT TYPE variables where the selector was not a
dummy argument as the scan for the association target was too shallow.
Scan through association lists for the ultimate selector.

	PR fortran/123253

gcc/fortran/ChangeLog:

	* expr.cc (gfc_check_vardef_context): Replace simple check by a
	scan through the association targets for a dummy argument.

gcc/testsuite/ChangeLog:

	* gfortran.dg/associate_76.f90: Extended testcase.
	* gfortran.dg/associate_77.f90: New test.
---
 gcc/fortran/expr.cc                        | 33 ++++++++---
 gcc/testsuite/gfortran.dg/associate_76.f90 | 38 ++++++++++++-
 gcc/testsuite/gfortran.dg/associate_77.f90 | 65 ++++++++++++++++++++++
 3 files changed, 127 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/associate_77.f90

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index d8d9009dc42..87587ee2010 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -6784,14 +6784,31 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj,
     }
 
   /* See if the INTENT(IN) check should apply to an ASSOCIATE target.  */
-  if (check_intentin
-      && sym->assoc
-      && sym->assoc->target
-      && sym->assoc->target->symtree
-      && sym->assoc->target->symtree->n.sym
-      && sym->assoc->target->symtree->n.sym->attr.dummy
-      && sym->assoc->target->symtree->n.sym->attr.intent != INTENT_IN)
-    check_intentin = false;
+  if (check_intentin && sym->assoc && sym->assoc->target)
+    {
+      gfc_expr *target;
+      gfc_symbol *tsym;
+
+      check_intentin = false;
+
+      /* Walk through associate target chain to find a dummy argument.  */
+      for (target = sym->assoc->target; target; target = tsym->assoc->target)
+	{
+	  tsym = target->symtree ? target->symtree->n.sym : NULL;
+
+	  if (tsym == NULL)
+	    break;
+
+	  if (tsym->attr.dummy)
+	    {
+	      check_intentin = (tsym->attr.intent == INTENT_IN);
+	      break;
+	    }
+
+	  if (tsym->assoc == NULL)
+	    break;
+	}
+    }
 
   if (check_intentin
       && (sym->attr.intent == INTENT_IN
diff --git a/gcc/testsuite/gfortran.dg/associate_76.f90 b/gcc/testsuite/gfortran.dg/associate_76.f90
index d76c052703e..7f1023fd19f 100644
--- a/gcc/testsuite/gfortran.dg/associate_76.f90
+++ b/gcc/testsuite/gfortran.dg/associate_76.f90
@@ -22,6 +22,14 @@ contains
        var%i = 3
        var%i => NULL()      ! { dg-error "pointer association context" }
     end select
+
+    associate (avar => var)
+      select type(avar)     ! { dg-error "variable definition context" }
+      class is(t_b)
+         avar%i = 3
+         avar%i => NULL()   ! { dg-error "variable definition context" }
+      end select
+    end associate
   end subroutine s1
 
   subroutine s1a(var)
@@ -31,8 +39,27 @@ contains
        tmp%i = 3
        tmp%i => NULL()      ! { dg-error "variable definition context" }
     end select
+
+    associate (avar => var)
+      select type(tmp => avar) ! { dg-error "variable definition context" }
+      class is(t_b)
+         tmp%i = 3
+         tmp%i => NULL()       ! { dg-error "variable definition context" }
+      end select
+    end associate
   end subroutine s1a
 
+  subroutine s1b(var)
+    class(t_a), intent(in) :: var
+    associate (avar => var)
+      select type(tmp => avar) ! { dg-error "variable definition context" }
+      class is(t_b)
+         tmp%i = 3
+         tmp%i => NULL()       ! { dg-error "variable definition context" }
+      end select
+    end associate
+  end subroutine s1b
+
   subroutine s2(var)
     class(t_b), intent(in) :: var
     var%i = 3
@@ -58,10 +85,19 @@ contains
   subroutine s3(var)
     class(t_a), intent(in) :: var
     integer, pointer :: tmp
-    select type(var); class is(t_b)
+    select type(var)
+    class is(t_b)
        tmp => var%i
        tmp =  3
     end select
+
+    associate (avar => var)
+      select type(avar)
+      class is(t_b)
+         tmp => avar%i
+         tmp =  3
+      end select
+    end associate
   end subroutine s3
 
 end module m
diff --git a/gcc/testsuite/gfortran.dg/associate_77.f90 b/gcc/testsuite/gfortran.dg/associate_77.f90
new file mode 100644
index 00000000000..6e80595711f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_77.f90
@@ -0,0 +1,65 @@
+! { dg-do compile }
+! PR fortran/123253 - pointer assignment checks in SELECT TYPE
+!
+! Contributed by Jürgen Reuter
+
+module vamp
+  implicit none
+  private
+  type, public :: vamp_data_t
+  end type vamp_data_t
+end module vamp
+
+module mci_vamp
+  use vamp !NODEP!
+  implicit none
+  private
+
+  type, abstract :: mci_sampler_t
+  end type mci_sampler_t
+
+  type :: mci_vamp_t
+   contains
+     procedure :: generate_weighted_event => mci_vamp_generate_weighted_event
+  end type mci_vamp_t
+
+  type, extends (vamp_data_t) :: mci_workspace_t
+     class(mci_sampler_t), pointer :: sampler => null ()
+     class(mci_vamp_instance_t), pointer :: instance => null ()
+  end type mci_workspace_t
+
+  type :: mci_vamp_instance_t
+     type(mci_vamp_t), pointer :: mci => null ()
+  end type mci_vamp_instance_t
+
+contains
+
+  subroutine mci_vamp_generate_weighted_event (mci, instance, sampler)
+    class(mci_vamp_t), intent(inout) :: mci
+    class(mci_vamp_instance_t), intent(inout), target :: instance
+    class(mci_sampler_t), intent(inout), target :: sampler
+    class(vamp_data_t), allocatable :: data
+
+    select type (instance)
+    type is (mci_vamp_instance_t)
+       allocate (mci_workspace_t :: data)
+       select type (data)
+       type is (mci_workspace_t)
+          data%sampler => sampler
+          data%instance => instance
+       end select
+    end select
+
+    select type (foo_instance => instance)
+    type is (mci_vamp_instance_t)
+       allocate (mci_workspace_t :: data)
+       select type (tmp => data)
+       type is (mci_workspace_t)
+          tmp%sampler => sampler
+          tmp%instance => foo_instance
+       end select
+    end select
+
+  end subroutine mci_vamp_generate_weighted_event
+
+end module mci_vamp
-- 
2.51.0

Reply via email to