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

via flang-commits flang-commits at lists.llvm.org
Fri Oct 9 04:06:50 PDT 2026


Author: Eugene Epshteyn
Date: 2026-10-09T11:06:44Z
New Revision: 6511483771924a83a901af4e401b18e1aa450d5f

URL: https://github.com/llvm/llvm-project/commit/6511483771924a83a901af4e401b18e1aa450d5f
DIFF: https://github.com/llvm/llvm-project/commit/6511483771924a83a901af4e401b18e1aa450d5f.diff

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

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. The DO statement of an unnamed labeled DO loop has no construct
name, so a name on its END DO 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, the kernels
and serial loop constructs, and a named labeled DO loop whose END DO
specifies the same name.

Assisted-by: AI

Added: 
    flang/test/Parser/acc-label-do-end-name.f90

Modified: 
    flang/lib/Parser/openacc-parsers.cpp
    flang/test/Semantics/OpenACC/acc-label-do.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index d39196dc4f0ce9..bed9f3f8327727 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -237,11 +237,18 @@ 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.  Only an unnamed labeled DO
+    // statement is parsed here (a named one is parsed as a DO construct), so
+    // a construct name on the END DO statement is not allowed (C1135);
+    // diagnose it before it is lost.
     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..71e352a46505a0
--- /dev/null
+++ b/flang/test/Parser/acc-label-do-end-name.f90
@@ -0,0 +1,53 @@
+! RUN: not %flang_fc1 -fopenacc -fsyntax-only %s 2>&1 | FileCheck %s --implicit-check-not="Unexpected DO construct name"
+
+! The END DO statement that terminates an unnamed labeled DO loop must not
+! specify a construct name (C1135), 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
+
+! A named labeled DO loop may be terminated by an END DO statement with the
+! same name.
+
+subroutine named(a, n)
+  integer :: n, i
+  real :: a(n)
+  !$acc parallel loop
+  foo: do 50 i = 1, n
+    a(i) = 0
+50 end do foo
+end subroutine

diff  --git a/flang/test/Semantics/OpenACC/acc-label-do.f90 b/flang/test/Semantics/OpenACC/acc-label-do.f90
index dc758e29b70f5c..a732d637d8587f 100644
--- a/flang/test/Semantics/OpenACC/acc-label-do.f90
+++ b/flang/test/Semantics/OpenACC/acc-label-do.f90
@@ -86,3 +86,52 @@ 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
+
+subroutine named_label_do(c, np)
+  integer :: np, n
+  real :: c(np)
+  !$acc parallel loop
+  foo: do 100 n = 1, np
+    c(n) = 0
+100 end do foo
+end subroutine


        


More information about the flang-commits mailing list