[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:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-parser
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