[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