https://gcc.gnu.org/g:30078cb0cc5e19d3de55d218ae500d59a21e7537

commit r15-5767-g30078cb0cc5e19d3de55d218ae500d59a21e7537
Author: Steven G. Kargl <kar...@comcast.net>
Date:   Thu Nov 28 13:37:02 2024 -0800

    Fortran: Check for impure subroutine.
    
            PR fortran/117765
    
    gcc/fortran/ChangeLog:
    
            * resolve.cc (pure_subroutine): Check for an impure subroutine
            call in a BLOCK construct nested within a DO CONCURRENT block.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/impure_fcn_do_concurrent.f90: Update test to catch
            calls to an impure subroutine.

Diff:
---
 gcc/fortran/resolve.cc                                 | 18 ++++++++++++++++++
 gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 |  9 ++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 304bf208d1a9..f892d809d209 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -3603,9 +3603,27 @@ resolve_function (gfc_expr *expr)
 static bool
 pure_subroutine (gfc_symbol *sym, const char *name, locus *loc)
 {
+  code_stack *stack;
+  bool saw_block = false;
+
   if (gfc_pure (sym))
     return true;
 
+  /* A BLOCK construct within a DO CONCURRENT construct leads to
+     gfc_do_concurrent_flag = 0 when the check for an impure subroutine
+     occurs.  Check the stack to see if the source code has a nested
+     BLOCK construct.  */
+  for (stack = cs_base; stack; stack = stack->prev)
+    {
+      if (stack->current->op == EXEC_BLOCK) saw_block = true;
+      if (saw_block && stack->current->op == EXEC_DO_CONCURRENT)
+       {
+         gfc_error ("Subroutine call at %L in a DO CONCURRENT block "
+                    "is not PURE", loc);
+         return false;
+       }
+    }
+
   if (forall_flag)
     {
       gfc_error ("Subroutine call to %qs in FORALL block at %L is not PURE",
diff --git a/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 
b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90
index af524ae83f3c..5846f8c68aab 100644
--- a/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90
+++ b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90
@@ -10,12 +10,14 @@ program foo
 
    do concurrent(i=1:4)
       y(i) = bar(i)        ! { dg-error "Reference to impure function" }
+      call bla(i)          ! { dg-error "Subroutine call to" }
    end do
 
    do concurrent(i=1:4)
       block
          y(i) = bar(i)     ! { dg-error "Reference to impure function" }
-      end block
+         call bla(i)       ! { dg-error "Subroutine call at" }
+       end block
    end do
 
    contains
@@ -27,4 +29,9 @@ program foo
          bar = j
       end function bar
 
+      impure subroutine bla (i)
+         integer, intent(in) :: i
+         j = j + i
+      end subroutine bla
+
 end program foo

Reply via email to