[llvm-branch-commits] [flang] [flang][OpenMP] move omp end sections validation to semantics (PR #154740)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 21 04:58:06 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Tom Eccles (tblah)
<details>
<summary>Changes</summary>
See #<!-- -->90452. The old parse tree errors exploded to thousands of unhelpful lines when there were multiple missing end directives.
Instead, allow a missing end directive in the parse tree then validate that it is present during semantics (where the error messages are a lot easier to control).
---
Full diff: https://github.com/llvm/llvm-project/pull/154740.diff
6 Files Affected:
- (modified) flang/include/flang/Parser/parse-tree.h (+4-1)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+5-2)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+1-1)
- (modified) flang/lib/Parser/unparse.cpp (+1-1)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+13-4)
- (modified) flang/test/Semantics/OpenMP/missing-end-directive.f90 (+4)
``````````diff
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 38ec605574c06..9962a25c29600 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4903,8 +4903,11 @@ struct OpenMPSectionsConstruct {
CharBlock source;
// Each of the OpenMPConstructs in the list below contains an
// OpenMPSectionConstruct. This is guaranteed by the parser.
+ // The end sections directive is optional here because it is difficult to
+ // generate helpful error messages for a missing end directive wihtin the
+ // parser. Semantics will generate an error if this is absent.
std::tuple<OmpBeginSectionsDirective, std::list<OpenMPConstruct>,
- OmpEndSectionsDirective>
+ std::optional<OmpEndSectionsDirective>>
t;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ec2ec37e623f8..da5898480da22 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3958,9 +3958,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
List<Clause> clauses = makeClauses(
std::get<parser::OmpClauseList>(beginSectionsDirective.t), semaCtx);
const auto &endSectionsDirective =
- std::get<parser::OmpEndSectionsDirective>(sectionsConstruct.t);
+ std::get<std::optional<parser::OmpEndSectionsDirective>>(
+ sectionsConstruct.t);
+ assert(endSectionsDirective &&
+ "Missing end section directive should have been handled in semantics");
clauses.append(makeClauses(
- std::get<parser::OmpClauseList>(endSectionsDirective.t), semaCtx));
+ std::get<parser::OmpClauseList>(endSectionsDirective->t), semaCtx));
mlir::Location currentLocation = converter.getCurrentLocation();
llvm::omp::Directive directive =
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 9670302c8549b..d7db3d55c3e17 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1919,7 +1919,7 @@ TYPE_PARSER(sourced(construct<OpenMPSectionsConstruct>(
construct<OpenMPSectionConstruct>(maybe(sectionDir), block))),
many(construct<OpenMPConstruct>(
sourced(construct<OpenMPSectionConstruct>(sectionDir, block))))),
- Parser<OmpEndSectionsDirective>{} / endOmpLine)))
+ maybe(Parser<OmpEndSectionsDirective>{} / endOmpLine))))
static bool IsExecutionPart(const OmpDirectiveName &name) {
return name.IsExecutionPart();
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 09dcfe60a46bc..87e699dbc4e8d 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2788,7 +2788,7 @@ class UnparseVisitor {
Walk(std::get<std::list<OpenMPConstruct>>(x.t), "");
BeginOpenMP();
Word("!$OMP END ");
- Walk(std::get<OmpEndSectionsDirective>(x.t));
+ Walk(std::get<std::optional<OmpEndSectionsDirective>>(x.t));
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 0bdd2c62f88ce..4a52e06cccb1f 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1047,14 +1047,23 @@ void OmpStructureChecker::Leave(const parser::OmpBeginDirective &) {
void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
const auto &beginSectionsDir{
std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &endSectionsDir{std::get<parser::OmpEndSectionsDirective>(x.t)};
+ const auto &endSectionsDir{
+ std::get<std::optional<parser::OmpEndSectionsDirective>>(x.t)};
const auto &beginDir{
std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir.t)};
+ PushContextAndClauseSets(beginDir.source, beginDir.v);
+
+ if (!endSectionsDir) {
+ context_.Say(beginSectionsDir.source,
+ "Expected OpenMP END SECTIONS directive"_err_en_US);
+ // Following code assumes the option is present.
+ return;
+ }
+
+ const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir->t)};
CheckMatching<parser::OmpSectionsDirective>(beginDir, endDir);
- PushContextAndClauseSets(beginDir.source, beginDir.v);
- AddEndDirectiveClauses(std::get<parser::OmpClauseList>(endSectionsDir.t));
+ AddEndDirectiveClauses(std::get<parser::OmpClauseList>(endSectionsDir->t));
const auto §ionBlocks{std::get<std::list<parser::OpenMPConstruct>>(x.t)};
for (const parser::OpenMPConstruct &construct : sectionBlocks) {
diff --git a/flang/test/Semantics/OpenMP/missing-end-directive.f90 b/flang/test/Semantics/OpenMP/missing-end-directive.f90
index 3b870d134155b..33481f9d650f4 100644
--- a/flang/test/Semantics/OpenMP/missing-end-directive.f90
+++ b/flang/test/Semantics/OpenMP/missing-end-directive.f90
@@ -6,8 +6,12 @@
!$omp parallel
! ERROR: Expected OpenMP end directive
!$omp task
+! ERROR: Expected OpenMP END SECTIONS directive
+!$omp sections
! ERROR: Expected OpenMP end directive
!$omp parallel
! ERROR: Expected OpenMP end directive
!$omp task
+! ERROR: Expected OpenMP END SECTIONS directive
+!$omp sections
end
``````````
</details>
https://github.com/llvm/llvm-project/pull/154740
More information about the llvm-branch-commits
mailing list