[flang-commits] [flang] [flang][OpenMP] Properly resolve CRITICAL construct names (PR #205904)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Fri Jun 26 08:26:13 PDT 2026


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/205904

>From 2727c4cbdc03f0da2527e56870e6b1fc7ef6eadf Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 25 Jun 2026 13:05:22 -0500
Subject: [PATCH 1/4] [flang][OpenMP] Properly resolve CRITICAL construct names

Resolve the names of CRITICAL constructs even if they are reserved names.

Fixes https://github.com/llvm/llvm-project/issues/205855
---
 flang/lib/Semantics/check-omp-structure.cpp   |  7 ++-
 flang/lib/Semantics/resolve-names.cpp         | 52 +++++++++++--------
 .../OpenMP/critical-reserved-name.f90         |  8 +++
 .../Semantics/OpenMP/reserved-locator.f90     |  2 +-
 4 files changed, 46 insertions(+), 23 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/critical-reserved-name.f90

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 061b2bdf775d0..fcd5e884db18d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -649,7 +649,7 @@ void OmpStructureChecker::Enter(const parser::OmpLocator &x) {
   if (auto *reserved{parser::Unwrap<parser::OmpReservedIdentifier>(x.u)}) {
     std::string name{parser::ToLowerCaseLetters(reserved->v.source.ToString())};
     if (!llvm::is_contained(llvm::omp::getReservedLocatorNames(), name)) {
-      context_.Say(reserved->v.source, "'%s' is not a valid locator"_err_en_US,
+      context_.Say(reserved->v.source, "Invalid use of a reserved name '%s'"_err_en_US,
           parser::ToUpperCaseLetters(name));
     }
   }
@@ -3099,6 +3099,11 @@ void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
     if (auto *object{parser::Unwrap<parser::OmpObject>(arg.u)}) {
       if (auto *designator{GetDesignatorFromObj(*object)}) {
         return parser::GetDesignatorNameIfDataRef(*designator);
+      } else if (auto *locator{std::get_if<parser::OmpLocator>(&object->u)}) {
+        if (auto *res{
+                std::get_if<parser::OmpReservedIdentifier>(&locator->u)}) {
+          return &res->v;
+        }
       }
     }
     return static_cast<const parser::Name *>(nullptr);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 11e24a5e1cccb..8f7d5f0d3f959 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2168,29 +2168,39 @@ void OmpVisitor::ProcessReductionSpecifier(
 }
 
 void OmpVisitor::ResolveCriticalName(const parser::OmpArgument &arg) {
-  auto &globalScope{[&]() -> Scope & {
-    for (Scope *s{&currScope()};; s = &s->parent()) {
-      if (s->IsTopLevel()) {
-        return *s;
-      }
-    }
-    llvm_unreachable("Cannot find global scope");
-  }()};
+  auto *object{parser::Unwrap<parser::OmpObject>(arg.u)};
+  if (!object) {
+    return;
+  }
 
-  if (auto *object{parser::Unwrap<parser::OmpObject>(arg.u)}) {
-    if (auto *desg{parser::omp::GetDesignatorFromObj(*object)}) {
-      if (auto *name{parser::GetDesignatorNameIfDataRef(*desg)}) {
-        if (auto *symbol{FindInScope(globalScope, *name)}) {
-          if (!symbol->test(Symbol::Flag::OmpCriticalLock)) {
-            SayWithDecl(*name, *symbol,
-                "CRITICAL construct name '%s' conflicts with a previous declaration"_warn_en_US,
-                name->ToString());
-          }
-        } else {
-          name->symbol = &MakeSymbol(globalScope, name->source, Attrs{});
-          name->symbol->set(Symbol::Flag::OmpCriticalLock);
-        }
+  const parser::Name *name{common::visit( //
+      common::visitors{//
+          [&](const parser::Designator &x) -> const parser::Name * {
+            return parser::GetDesignatorNameIfDataRef(x);
+          },
+          [&](const parser::OmpLocator &x) -> const parser::Name * {
+            if (auto *res{std::get_if<parser::OmpReservedIdentifier>(&x.u)}) {
+              return &res->v;
+            }
+            return nullptr;
+          },
+          [&](const parser::Name &) -> const parser::Name * { return nullptr; },
+          [&](const parser::OmpObject::Invalid &) -> const parser::Name * {
+            return nullptr;
+          }},
+      object->u)};
+
+  if (name) {
+    if (auto *symbol{FindInScope(context().globalScope(), *name)}) {
+      if (!symbol->test(Symbol::Flag::OmpCriticalLock)) {
+        SayWithDecl(*name, *symbol,
+            "CRITICAL construct name '%s' conflicts with a previous declaration"_warn_en_US,
+            name->ToString());
       }
+    } else {
+      name->symbol =
+          &MakeSymbol(context().globalScope(), name->source, Attrs{});
+      name->symbol->set(Symbol::Flag::OmpCriticalLock);
     }
   }
 }
diff --git a/flang/test/Semantics/OpenMP/critical-reserved-name.f90 b/flang/test/Semantics/OpenMP/critical-reserved-name.f90
new file mode 100644
index 0000000000000..9516f0c07d7b7
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/critical-reserved-name.f90
@@ -0,0 +1,8 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+subroutine f
+  !ERROR: Invalid use of a reserved name 'OMP_C'
+  !$omp critical(omp_c)
+  !ERROR: Invalid use of a reserved name 'OMP_C'
+  !$omp end critical(omp_c)
+end
diff --git a/flang/test/Semantics/OpenMP/reserved-locator.f90 b/flang/test/Semantics/OpenMP/reserved-locator.f90
index 3fc45ffa0f54c..ae2a6d59f4c74 100644
--- a/flang/test/Semantics/OpenMP/reserved-locator.f90
+++ b/flang/test/Semantics/OpenMP/reserved-locator.f90
@@ -1,6 +1,6 @@
 !RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=60
 
 subroutine f
-!ERROR: 'OMP_SOME_MEMORY' is not a valid locator
+!ERROR: Invalid use of a reserved name 'OMP_SOME_MEMORY'
   !$omp target update from(omp_some_memory)
 end

>From 4b7b7ec920bdb90be724fb2150688b19f2a860bc Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 25 Jun 2026 15:20:33 -0500
Subject: [PATCH 2/4] format

---
 flang/lib/Semantics/check-omp-structure.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index fcd5e884db18d..61c54bcf69520 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -649,7 +649,8 @@ void OmpStructureChecker::Enter(const parser::OmpLocator &x) {
   if (auto *reserved{parser::Unwrap<parser::OmpReservedIdentifier>(x.u)}) {
     std::string name{parser::ToLowerCaseLetters(reserved->v.source.ToString())};
     if (!llvm::is_contained(llvm::omp::getReservedLocatorNames(), name)) {
-      context_.Say(reserved->v.source, "Invalid use of a reserved name '%s'"_err_en_US,
+      context_.Say(reserved->v.source,
+          "Invalid use of a reserved name '%s'"_err_en_US,
           parser::ToUpperCaseLetters(name));
     }
   }

>From 1c0d6df8ad9ab42eaa657c7006e0f96715eb340d Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 26 Jun 2026 07:56:56 -0500
Subject: [PATCH 3/4] Make OmpLocator parser only handle known locator names

---
 flang/lib/Parser/openmp-parsers.cpp           | 25 ++++++++++++++++---
 .../OpenMP/critical-reserved-name.f90         |  8 ------
 .../Semantics/OpenMP/reserved-locator.f90     |  6 -----
 3 files changed, 21 insertions(+), 18 deletions(-)
 delete mode 100644 flang/test/Semantics/OpenMP/critical-reserved-name.f90
 delete mode 100644 flang/test/Semantics/OpenMP/reserved-locator.f90

diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 8a18bcc9e4485..1957c7c5947cd 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -290,10 +290,27 @@ static bool IsReservedName(const Name &name) {
 TYPE_PARSER( //
     construct<OmpReservedIdentifier>(predicated(name, IsReservedName)))
 
-// Parse x(...)(...) as a substring instead of a function reference.
-TYPE_PARSER( //
-    construct<OmpLocator>(functionReference / !lookAhead("("_tok)) ||
-    construct<OmpLocator>(Parser<OmpReservedIdentifier>{}))
+struct LocatorParser {
+  using resultType = OmpLocator;
+  using Token = TokenStringMatch<false, false>;
+
+  std::optional<resultType> Parse(ParseState &state) const {
+    // Parse x(...)(...) as a substring instead of a function reference.
+    auto funcRef{functionReference / !lookAhead("("_tok)};
+    if (auto &&result{attempt(funcRef).Parse(state)}) {
+      return std::move(*result);
+    }
+    for (llvm::StringRef n : llvm::omp::getReservedLocatorNames()) {
+      auto match{Token(n.data(), n.size())};
+      if (auto &&result{attempt(match >= name).Parse(state)}) {
+        return OmpReservedIdentifier(std::move(*result));
+      }
+    }
+    return std::nullopt;
+  }
+};
+
+TYPE_PARSER(construct<OmpLocator>(LocatorParser{}))
 
 TYPE_PARSER( //
     construct<OmpObject>(Parser<OmpLocator>{}) ||
diff --git a/flang/test/Semantics/OpenMP/critical-reserved-name.f90 b/flang/test/Semantics/OpenMP/critical-reserved-name.f90
deleted file mode 100644
index 9516f0c07d7b7..0000000000000
--- a/flang/test/Semantics/OpenMP/critical-reserved-name.f90
+++ /dev/null
@@ -1,8 +0,0 @@
-! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
-
-subroutine f
-  !ERROR: Invalid use of a reserved name 'OMP_C'
-  !$omp critical(omp_c)
-  !ERROR: Invalid use of a reserved name 'OMP_C'
-  !$omp end critical(omp_c)
-end
diff --git a/flang/test/Semantics/OpenMP/reserved-locator.f90 b/flang/test/Semantics/OpenMP/reserved-locator.f90
deleted file mode 100644
index ae2a6d59f4c74..0000000000000
--- a/flang/test/Semantics/OpenMP/reserved-locator.f90
+++ /dev/null
@@ -1,6 +0,0 @@
-!RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=60
-
-subroutine f
-!ERROR: Invalid use of a reserved name 'OMP_SOME_MEMORY'
-  !$omp target update from(omp_some_memory)
-end

>From 543ee60a51cf9dd0384dac128aad0f43a0ff5f84 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 26 Jun 2026 10:22:34 -0500
Subject: [PATCH 4/4] Remove unused locator check

---
 flang/lib/Semantics/check-omp-structure.cpp | 11 -----------
 flang/lib/Semantics/check-omp-structure.h   |  1 -
 2 files changed, 12 deletions(-)

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 369d1f7a3b11d..faced12ae92ac 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -649,17 +649,6 @@ bool OmpStructureChecker::HasRequires(llvm::omp::Clause req) {
       DEREF(unit.symbol()).details());
 }
 
-void OmpStructureChecker::Enter(const parser::OmpLocator &x) {
-  if (auto *reserved{parser::Unwrap<parser::OmpReservedIdentifier>(x.u)}) {
-    std::string name{parser::ToLowerCaseLetters(reserved->v.source.ToString())};
-    if (!llvm::is_contained(llvm::omp::getReservedLocatorNames(), name)) {
-      context_.Say(reserved->v.source,
-          "Invalid use of a reserved name '%s'"_err_en_US,
-          parser::ToUpperCaseLetters(name));
-    }
-  }
-}
-
 void OmpStructureChecker::CheckArgumentObjectKind(const parser::OmpClause &x) {
   unsigned version{context_.langOptions().OpenMPVersion};
   llvm::omp::Directive dirId{GetContext().directive};
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index f275717135874..011b29d370ba3 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -128,7 +128,6 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   void Enter(const parser::OpenMPCriticalConstruct &);
   void Enter(const parser::OpenMPAtomicConstruct &);
 
-  void Enter(const parser::OmpLocator &x);
   void Enter(const parser::OmpClauseList &);
   void Leave(const parser::OmpClauseList &);
   void Enter(const parser::OmpClause &);



More information about the flang-commits mailing list