[flang-commits] [flang] [flang][OpenMP] Refactor semantic check of SINGLE construct (PR #204339)
Thirumalai Shaktivel via flang-commits
flang-commits at lists.llvm.org
Sun Jun 21 21:37:55 PDT 2026
================
@@ -1386,6 +1330,78 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
}
}
+void OmpStructureChecker::CheckSingleConstruct(
+ const parser::OmpBlockConstruct &x) {
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ unsigned version{context_.langOptions().OpenMPVersion};
+ SymbolSourceMap copyPrivateSyms;
+ parser::CharBlock nowaitSource1, nowaitSource2;
+
+ auto catchCopyPrivateNowaitClauses =
+ [&](const parser::OmpDirectiveSpecification &spec,
+ parser::CharBlock &nowaitSource) {
+ for (auto &clause : spec.Clauses().v) {
+ llvm::omp::Clause clauseId{clause.Id()};
+ if (clauseId == llvm::omp::Clause::OMPC_copyprivate) {
+ GetSymbolsInObjectList(*GetOmpObjectList(clause), copyPrivateSyms);
+ } else if (clauseId == llvm::omp::Clause::OMPC_nowait) {
+ if (nowaitSource.empty()) {
+ nowaitSource = clause.source;
+ }
+ }
+ }
+ };
+
+ catchCopyPrivateNowaitClauses(beginSpec, nowaitSource1);
+ if (auto &endSpec{x.EndDir()}) {
+ catchCopyPrivateNowaitClauses(*endSpec, nowaitSource2);
+ }
+
+ std::string nowaitName{//
+ GetUpperName(llvm::omp::Clause::OMPC_nowait, version)};
+ std::string copyPrivateName{
+ GetUpperName(llvm::omp::Clause::OMPC_copyprivate, version)};
+ std::string singleName{
+ GetUpperName(llvm::omp::Directive::OMPD_single, version)};
+
+ std::pair<const Symbol *, parser::CharBlock> last{nullptr, {}};
+ bool reported{false};
+
+ for (auto [symbol, source] : copyPrivateSyms) {
+ if (symbol == last.first) {
+ if (!reported) {
+ context_
+ .Say(source, "'%s' appears more than once in a %s clause"_err_en_US,
+ symbol->name().ToString(), copyPrivateName)
+ .Attach(last.second, "Previous occurrence of '%s'"_en_US,
+ symbol->name().ToString());
+ reported = true;
+ }
+ } else {
+ reported = false;
+ }
+ last = std::make_pair(symbol, source);
+ }
+
+ if (!nowaitSource1.empty() && !nowaitSource2.empty()) {
+ context_
+ .Say(nowaitSource2,
+ // Match the message text with the one emitted by "CheckAllowed".
+ "At most one %s clause can appear on the %s directive"_err_en_US,
+ nowaitName, singleName)
+ .Attach(nowaitSource1, "Previous occurrence of %s"_en_US, nowaitName);
+ }
+
+ if (version < 52 && !copyPrivateSyms.empty() &&
----------------
Thirumalai-Shaktivel wrote:
This excludes the 5.2 version for the semantic restriction
OpenMP 5.2 doc: 11.1
```
The copyprivate clause must not be used with the nowait clause
```
Example in godbolt: https://godbolt.org/z/4GbP19hjf
https://github.com/llvm/llvm-project/pull/204339
More information about the flang-commits
mailing list