[flang-commits] [flang] [flang][openacc] Ignore bare acc routine in module subprogram part instead of erroring out (PR #205450)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Wed Jun 24 14:51:00 PDT 2026


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/205450

>From eaced713de403fed0784efb16078d97dcee50190 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 23 Jun 2026 16:15:14 -0700
Subject: [PATCH 1/5] [flang][openacc] Ignore bare acc routine in module
 subprogram part instead of erroring out

---
 flang/lib/Parser/program-parsers.cpp         |  8 ++++++++
 flang/test/Lower/OpenACC/acc-routine-bad.f90 | 11 +++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 flang/test/Lower/OpenACC/acc-routine-bad.f90

diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index da8cd6fa27b65..a73dde8f5c81c 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -88,6 +88,13 @@ static constexpr auto globalOpenACCCompilerDirective{
     construct<ProgramUnit>(indirect(skipStuffBeforeStatement >>
         "!$ACC "_sptok >> Parser<OpenACCRoutineConstruct>{} / endOfLine))};
 
+// In a module-subprogram-part, a bare `!$ACC ROUTINE` line (without a name)
+// cannot be attached to a specific routine. Accept and ignore it so parsing
+// can continue to the following subprogram.
+static constexpr auto ignoredBareRoutineOpenACCDirective{
+    (skipStuffBeforeStatement >> "!$ACC "_sptok >> "ROUTINE"_tok / endOfLine) >>
+    construct<CompilerDirective>(pure<CompilerDirective::Unrecognized>())};
+
 // R501 program -> program-unit [program-unit]...
 // This is the top-level production for the Fortran language.
 TYPE_PARSER(construct<Program>(skipStuffBeforeStatement >>
@@ -294,6 +301,7 @@ TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
 TYPE_PARSER(construct<ModuleSubprogram>(indirect(functionSubprogram)) ||
     construct<ModuleSubprogram>(indirect(subroutineSubprogram)) ||
     construct<ModuleSubprogram>(indirect(Parser<SeparateModuleSubprogram>{})) ||
+    construct<ModuleSubprogram>(indirect(ignoredBareRoutineOpenACCDirective)) ||
     construct<ModuleSubprogram>(indirect(compilerDirective)))
 
 // R1410 module-nature -> INTRINSIC | NON_INTRINSIC
diff --git a/flang/test/Lower/OpenACC/acc-routine-bad.f90 b/flang/test/Lower/OpenACC/acc-routine-bad.f90
new file mode 100644
index 0000000000000..1d9b73c12ac7d
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-routine-bad.f90
@@ -0,0 +1,11 @@
+! RUN: bbc -fopenacc -emit-hlfir %s -o - 2>&1 | FileCheck %s
+
+module acc_routine_bad
+
+contains
+!$acc routine
+subroutine acc_routine20()
+end subroutine
+end module
+
+!CHECK: {{.*}}warning: Compiler directive ignored here{{.*}}

>From bd271e03b9c8e5b90825df4136493845c7f40ddf Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 23 Jun 2026 16:54:43 -0700
Subject: [PATCH 2/5] Add more precise warning

---
 flang/lib/Parser/program-parsers.cpp         | 15 ++++++++++++++-
 flang/test/Lower/OpenACC/acc-routine-bad.f90 |  2 +-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index a73dde8f5c81c..dcef0a6742db7 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -88,11 +88,24 @@ static constexpr auto globalOpenACCCompilerDirective{
     construct<ProgramUnit>(indirect(skipStuffBeforeStatement >>
         "!$ACC "_sptok >> Parser<OpenACCRoutineConstruct>{} / endOfLine))};
 
+struct WarnUnnamedOpenACCRoutineDirective {
+  using resultType = Success;
+  std::optional<Success> Parse(ParseState &state) const {
+    state.Say("OpenACC routine directive without name must be placed in a "
+              "subroutine or function"_warn_en_US);
+    return {Success{}};
+  }
+};
+static constexpr WarnUnnamedOpenACCRoutineDirective
+    warnUnnamedOpenACCRoutineDirective;
+
 // In a module-subprogram-part, a bare `!$ACC ROUTINE` line (without a name)
 // cannot be attached to a specific routine. Accept and ignore it so parsing
 // can continue to the following subprogram.
 static constexpr auto ignoredBareRoutineOpenACCDirective{
-    (skipStuffBeforeStatement >> "!$ACC "_sptok >> "ROUTINE"_tok / endOfLine) >>
+    ((skipStuffBeforeStatement >> "!$ACC "_sptok >>
+         "ROUTINE"_tok / endOfLine) >>
+        warnUnnamedOpenACCRoutineDirective) >>
     construct<CompilerDirective>(pure<CompilerDirective::Unrecognized>())};
 
 // R501 program -> program-unit [program-unit]...
diff --git a/flang/test/Lower/OpenACC/acc-routine-bad.f90 b/flang/test/Lower/OpenACC/acc-routine-bad.f90
index 1d9b73c12ac7d..f1cead6633a65 100644
--- a/flang/test/Lower/OpenACC/acc-routine-bad.f90
+++ b/flang/test/Lower/OpenACC/acc-routine-bad.f90
@@ -8,4 +8,4 @@ subroutine acc_routine20()
 end subroutine
 end module
 
-!CHECK: {{.*}}warning: Compiler directive ignored here{{.*}}
+!CHECK: {{.*}}warning: OpenACC routine directive without name must be placed in a subroutine or function

>From fd59dd28f569ce03646814439d72485b47a7887c Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 23 Jun 2026 20:40:17 -0700
Subject: [PATCH 3/5] Move test to semantic

---
 flang/test/Lower/OpenACC/acc-routine-bad.f90     | 11 -----------
 flang/test/Semantics/OpenACC/acc-routine-bad.f90 | 10 ++++++++++
 2 files changed, 10 insertions(+), 11 deletions(-)
 delete mode 100644 flang/test/Lower/OpenACC/acc-routine-bad.f90
 create mode 100644 flang/test/Semantics/OpenACC/acc-routine-bad.f90

diff --git a/flang/test/Lower/OpenACC/acc-routine-bad.f90 b/flang/test/Lower/OpenACC/acc-routine-bad.f90
deleted file mode 100644
index f1cead6633a65..0000000000000
--- a/flang/test/Lower/OpenACC/acc-routine-bad.f90
+++ /dev/null
@@ -1,11 +0,0 @@
-! RUN: bbc -fopenacc -emit-hlfir %s -o - 2>&1 | FileCheck %s
-
-module acc_routine_bad
-
-contains
-!$acc routine
-subroutine acc_routine20()
-end subroutine
-end module
-
-!CHECK: {{.*}}warning: OpenACC routine directive without name must be placed in a subroutine or function
diff --git a/flang/test/Semantics/OpenACC/acc-routine-bad.f90 b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
new file mode 100644
index 0000000000000..92ab7bdcf15b9
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
@@ -0,0 +1,10 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -Werror
+
+module acc_routine_bad
+
+contains
+!$acc routine
+!WARNING: OpenACC routine directive without name must be placed in a subroutine or function
+subroutine acc_routine20()
+end subroutine
+end module

>From 50969f6bb8b5d6fbfc6cca6413ea1d36a3d92f09 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 24 Jun 2026 11:33:09 -0700
Subject: [PATCH 4/5] Use existing diagnostic for acc routine

---
 flang/include/flang/Parser/parse-tree.h       |  1 +
 flang/include/flang/Semantics/program-tree.h  |  2 ++
 flang/lib/Parser/program-parsers.cpp          | 22 +------------------
 flang/lib/Semantics/program-tree.cpp          |  5 +++++
 .../Semantics/OpenACC/acc-routine-bad.f90     |  2 +-
 5 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index ee6288539395c..26b1379606793 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -2986,6 +2986,7 @@ struct ModuleSubprogram {
   std::variant<common::Indirection<FunctionSubprogram>,
       common::Indirection<SubroutineSubprogram>,
       common::Indirection<SeparateModuleSubprogram>,
+      common::Indirection<OpenACCDeclarativeConstruct>,
       common::Indirection<CompilerDirective>>
       u;
 };
diff --git a/flang/include/flang/Semantics/program-tree.h b/flang/include/flang/Semantics/program-tree.h
index 1c89e6c175b96..ce53476511bfb 100644
--- a/flang/include/flang/Semantics/program-tree.h
+++ b/flang/include/flang/Semantics/program-tree.h
@@ -52,6 +52,8 @@ class ProgramTree {
       const parser::BlockData &, SemanticsContext &);
   static std::optional<ProgramTree> Build(
       const parser::CompilerDirective &, SemanticsContext &);
+  static std::optional<ProgramTree> Build(
+      const parser::OpenACCDeclarativeConstruct &, SemanticsContext &);
   static std::optional<ProgramTree> Build(
       const parser::OpenACCRoutineConstruct &, SemanticsContext &);
 
diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index dcef0a6742db7..1c9380d77d48f 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -88,26 +88,6 @@ static constexpr auto globalOpenACCCompilerDirective{
     construct<ProgramUnit>(indirect(skipStuffBeforeStatement >>
         "!$ACC "_sptok >> Parser<OpenACCRoutineConstruct>{} / endOfLine))};
 
-struct WarnUnnamedOpenACCRoutineDirective {
-  using resultType = Success;
-  std::optional<Success> Parse(ParseState &state) const {
-    state.Say("OpenACC routine directive without name must be placed in a "
-              "subroutine or function"_warn_en_US);
-    return {Success{}};
-  }
-};
-static constexpr WarnUnnamedOpenACCRoutineDirective
-    warnUnnamedOpenACCRoutineDirective;
-
-// In a module-subprogram-part, a bare `!$ACC ROUTINE` line (without a name)
-// cannot be attached to a specific routine. Accept and ignore it so parsing
-// can continue to the following subprogram.
-static constexpr auto ignoredBareRoutineOpenACCDirective{
-    ((skipStuffBeforeStatement >> "!$ACC "_sptok >>
-         "ROUTINE"_tok / endOfLine) >>
-        warnUnnamedOpenACCRoutineDirective) >>
-    construct<CompilerDirective>(pure<CompilerDirective::Unrecognized>())};
-
 // R501 program -> program-unit [program-unit]...
 // This is the top-level production for the Fortran language.
 TYPE_PARSER(construct<Program>(skipStuffBeforeStatement >>
@@ -314,7 +294,7 @@ TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
 TYPE_PARSER(construct<ModuleSubprogram>(indirect(functionSubprogram)) ||
     construct<ModuleSubprogram>(indirect(subroutineSubprogram)) ||
     construct<ModuleSubprogram>(indirect(Parser<SeparateModuleSubprogram>{})) ||
-    construct<ModuleSubprogram>(indirect(ignoredBareRoutineOpenACCDirective)) ||
+    construct<ModuleSubprogram>(indirect(openaccDeclarativeConstruct)) ||
     construct<ModuleSubprogram>(indirect(compilerDirective)))
 
 // R1410 module-nature -> INTRINSIC | NON_INTRINSIC
diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp
index 89517982de67c..214d285c6bc4f 100644
--- a/flang/lib/Semantics/program-tree.cpp
+++ b/flang/lib/Semantics/program-tree.cpp
@@ -232,6 +232,11 @@ std::optional<ProgramTree> ProgramTree::Build(
   return std::nullopt;
 }
 
+std::optional<ProgramTree> ProgramTree::Build(
+    const parser::OpenACCDeclarativeConstruct &, SemanticsContext &) {
+  return std::nullopt;
+}
+
 std::optional<ProgramTree> ProgramTree::Build(
     const parser::OpenACCRoutineConstruct &, SemanticsContext &) {
   DIE("ProgramTree::Build() called for OpenACCRoutineConstruct");
diff --git a/flang/test/Semantics/OpenACC/acc-routine-bad.f90 b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
index 92ab7bdcf15b9..2481f0a7923c4 100644
--- a/flang/test/Semantics/OpenACC/acc-routine-bad.f90
+++ b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
@@ -3,8 +3,8 @@
 module acc_routine_bad
 
 contains
+!ERROR: ROUTINE directive without name must appear within the specification part of a subroutine or function definition, or within an interface body for a subroutine or function in an interface block
 !$acc routine
-!WARNING: OpenACC routine directive without name must be placed in a subroutine or function
 subroutine acc_routine20()
 end subroutine
 end module

>From a5b02b2d8b4ecfc63f4a5439cb8a60204939e29e Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 24 Jun 2026 14:50:33 -0700
Subject: [PATCH 5/5] Add test for acc declare and remove -Werror

---
 flang/lib/Semantics/check-acc-structure.cpp           | 7 +++++--
 flang/test/Semantics/OpenACC/acc-declare-validity.f90 | 9 +++++++++
 flang/test/Semantics/OpenACC/acc-routine-bad.f90      | 2 +-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index ad8da4e9436a2..de4489932d37a 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -819,7 +819,8 @@ void AccStructureChecker::CheckMultipleOccurrenceInDeclare(
             [&](const parser::Designator &designator) {
               if (const auto *name =
                       parser::GetDesignatorNameIfDataRef(designator)) {
-                if (declareSymbols.contains(&name->symbol->GetUltimate())) {
+                if (name->symbol &&
+                    declareSymbols.contains(&name->symbol->GetUltimate())) {
                   if (declareSymbols[&name->symbol->GetUltimate()] == clause) {
                     context_.Warn(common::UsageWarning::OpenAccUsage,
                         GetContext().clauseSource,
@@ -840,7 +841,9 @@ void AccStructureChecker::CheckMultipleOccurrenceInDeclare(
                                 .str()));
                   }
                 }
-                declareSymbols.insert({&name->symbol->GetUltimate(), clause});
+                if (name->symbol) {
+                  declareSymbols.insert({&name->symbol->GetUltimate(), clause});
+                }
               }
             },
             [&](const parser::Name &name) {
diff --git a/flang/test/Semantics/OpenACC/acc-declare-validity.f90 b/flang/test/Semantics/OpenACC/acc-declare-validity.f90
index 3e40c964b002e..784ca0a01845a 100644
--- a/flang/test/Semantics/OpenACC/acc-declare-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-declare-validity.f90
@@ -84,3 +84,12 @@ subroutine sub3()
   end subroutine
 
 end module openacc_declare_validity
+
+
+module m
+  integer :: x
+contains
+  !$acc declare copyin(x)
+  subroutine s()
+  end subroutine
+end module
diff --git a/flang/test/Semantics/OpenACC/acc-routine-bad.f90 b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
index 2481f0a7923c4..3557495b1d9f0 100644
--- a/flang/test/Semantics/OpenACC/acc-routine-bad.f90
+++ b/flang/test/Semantics/OpenACC/acc-routine-bad.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenacc -Werror
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
 
 module acc_routine_bad
 



More information about the flang-commits mailing list