[flang-commits] [flang] [flang][openacc] Diagnose a construct name on the END DO of an ACC labeled DO (PR #230308)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 8 19:52:18 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Eugene Epshteyn (eugeneepshteyn)

<details>
<summary>Changes</summary>

When an OpenACC loop or combined construct is associated with a labeled DO
loop, AccNonBlockDoConstruct turns a terminating END DO statement into a
labeled CONTINUE statement, which silently dropped any construct name on the
END DO. A labeled DO statement has no construct name, so the name is not
allowed (C1135), and it is already diagnosed when the loop is not associated
with a directive:

```fortran
!$acc parallel loop
do 10 i = 1, n
  a(i) = 0
10 end do foo
```

Report "Unexpected DO construct name" at the name before it is dropped.
Also add tests for labeled END DO forms that are accepted: a branch to the
END DO from inside the loop, END DO followed by an end directive, and the
kernels and serial loop constructs.

Assisted-by: AI

---
Full diff: https://github.com/llvm/llvm-project/pull/230308.diff


3 Files Affected:

- (modified) flang/lib/Parser/openacc-parsers.cpp (+7-1) 
- (added) flang/test/Parser/acc-label-do-end-name.f90 (+41) 
- (modified) flang/test/Semantics/OpenACC/acc-label-do.f90 (+40) 


``````````diff
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index d39196dc4f0ce9..3b2c3826403fb3 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -237,11 +237,17 @@ struct AccNonBlockDoConstruct {
 
     // The terminating statement may be an END DO statement; the DO construct
     // built below has its own synthetic one, so turn it into a CONTINUE
-    // statement to keep its label and source.
+    // statement to keep its label and source.  A labeled DO statement has no
+    // construct name, so diagnose a name on the END DO statement before it is
+    // lost (C1135).
     if (auto *last{std::get_if<ExecutableConstruct>(&body.back().u)}) {
       if (auto *endDoStmt{
               std::get_if<Statement<common::Indirection<EndDoStmt>>>(
                   &last->u)}) {
+        if (const auto &name{endDoStmt->statement.value().v}) {
+          state.Say(name->source, "Unexpected DO construct name '%s'"_err_en_US,
+              name->source);
+        }
         Statement<ActionStmt> continueStmt{
             std::optional<Label>{endDoStmt->label}, ContinueStmt{}};
         continueStmt.source = endDoStmt->source;
diff --git a/flang/test/Parser/acc-label-do-end-name.f90 b/flang/test/Parser/acc-label-do-end-name.f90
new file mode 100644
index 00000000000000..5199fb60ced331
--- /dev/null
+++ b/flang/test/Parser/acc-label-do-end-name.f90
@@ -0,0 +1,41 @@
+! RUN: not %flang_fc1 -fopenacc -fsyntax-only %s 2>&1 | FileCheck %s --implicit-check-not="Unexpected DO construct name"
+
+! A labeled DO statement has no construct name, so the END DO statement that
+! terminates it must not specify one, also when the loop is associated with an
+! OpenACC loop or combined construct.
+
+subroutine combined(a, n)
+  integer :: n, i
+  real :: a(n)
+  !$acc parallel loop
+  do 10 i = 1, n
+    a(i) = 0
+10 end do foo
+! CHECK: :[[@LINE-1]]:11: error: Unexpected DO construct name 'foo'
+end subroutine
+
+subroutine nested(a, n, m)
+  integer :: n, m, i, j
+  real :: a(n, m)
+  !$acc parallel
+  !$acc loop collapse(2)
+  do 20 j = 1, m
+    do 30 i = 1, n
+      a(i, j) = 0
+30  end do inner
+! CHECK: :[[@LINE-1]]:12: error: Unexpected DO construct name 'inner'
+20 end do outer
+! CHECK: :[[@LINE-1]]:11: error: Unexpected DO construct name 'outer'
+  !$acc end parallel
+end subroutine
+
+subroutine shared(a, n, m)
+  integer :: n, m, i, j
+  real :: a(n, m)
+  !$acc parallel loop collapse(2)
+  do 40 j = 1, m
+    do 40 i = 1, n
+      a(i, j) = 0
+40 end do bar
+! CHECK: :[[@LINE-1]]:11: error: Unexpected DO construct name 'bar'
+end subroutine
diff --git a/flang/test/Semantics/OpenACC/acc-label-do.f90 b/flang/test/Semantics/OpenACC/acc-label-do.f90
index dc758e29b70f5c..3517e5d3797024 100644
--- a/flang/test/Semantics/OpenACC/acc-label-do.f90
+++ b/flang/test/Semantics/OpenACC/acc-label-do.f90
@@ -86,3 +86,43 @@ subroutine shared_end_do(a, n, m)
       a(i, j) = 1.0
 100 end do
 end subroutine
+
+subroutine goto_end_do(c, np)
+  integer :: np, n
+  real :: c(np)
+  !$acc parallel loop
+  do 100 n = 1, np
+    if (c(n) > 0) goto 100
+    c(n) = 0
+100 end do
+end subroutine
+
+subroutine end_directives(c, np)
+  integer :: np, n
+  real :: c(np)
+  !$acc parallel loop
+  do 100 n = 1, np
+    c(n) = 0
+100 end do
+  !$acc end parallel loop
+  !$acc parallel
+  !$acc loop
+  do 200 n = 1, np
+    c(n) = 1
+200 end do
+  !$acc end loop
+  !$acc end parallel
+end subroutine
+
+subroutine kernels_serial(c, np)
+  integer :: np, n
+  real :: c(np)
+  !$acc kernels loop
+  do 100 n = 1, np
+    c(n) = 0
+100 end do
+  !$acc serial loop
+  do 200 n = 1, np
+    c(n) = 1
+200 end do
+end subroutine

``````````

</details>


https://github.com/llvm/llvm-project/pull/230308


More information about the flang-commits mailing list