diff options
author | Steve Kargl <kargls@comcast.net> | 2024-11-24 18:26:03 -0800 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2024-11-25 09:32:42 -0800 |
commit | 7d92901c878c6c00ada7f9cee8825f03ad4722f1 (patch) | |
tree | 32a6788c73b1511fd8574fb1666ac1af958b9859 /gcc | |
parent | b82a5810e7bcc82b933e16f9067879b9d22b85c7 (diff) | |
download | gcc-7d92901c878c6c00ada7f9cee8825f03ad4722f1.zip gcc-7d92901c878c6c00ada7f9cee8825f03ad4722f1.tar.gz gcc-7d92901c878c6c00ada7f9cee8825f03ad4722f1.tar.bz2 |
Fortran: Check IMPURE in BLOCK inside DO CONCURRENT.
PR fortran/117765
gcc/fortran/ChangeLog:
* resolve.cc (check_pure_function): Check the stack to
see if the function is in a nested BLOCK and, if that
block is inside a DO_CONCURRENT, issue an error.
gcc/testsuite/ChangeLog:
* gfortran.dg/impure_fcn_do_concurrent.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/resolve.cc | 18 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 | 30 |
2 files changed, 48 insertions, 0 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index b1740ce..0d3845f 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -3227,6 +3227,24 @@ pure_stmt_function (gfc_expr *e, gfc_symbol *sym) static bool check_pure_function (gfc_expr *e) { const char *name = NULL; + code_stack *stack; + bool saw_block = false; + + /* A BLOCK construct within a DO CONCURRENT construct leads to + gfc_do_concurrent_flag = 0 when the check for an impure function + 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 ("Reference to impure function at %L inside a " + "DO CONCURRENT", &e->where); + return false; + } + } + if (!gfc_pure_function (e, &name) && name) { if (forall_flag) diff --git a/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 new file mode 100644 index 0000000..af524ae --- /dev/null +++ b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 @@ -0,0 +1,30 @@ +! { dg-do compile } +! +program foo + + implicit none + + integer i + integer :: j = 0 + real y(4) + + do concurrent(i=1:4) + y(i) = bar(i) ! { dg-error "Reference to impure function" } + end do + + do concurrent(i=1:4) + block + y(i) = bar(i) ! { dg-error "Reference to impure function" } + end block + end do + + contains + + impure function bar(i) + real bar + integer, intent(in) :: i + j = j + i + bar = j + end function bar + +end program foo |