aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSteve Kargl <kargls@comcast.net>2024-11-24 18:26:03 -0800
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2024-11-25 09:32:42 -0800
commit7d92901c878c6c00ada7f9cee8825f03ad4722f1 (patch)
tree32a6788c73b1511fd8574fb1666ac1af958b9859 /gcc
parentb82a5810e7bcc82b933e16f9067879b9d22b85c7 (diff)
downloadgcc-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.cc18
-rw-r--r--gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f9030
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