[flang-commits] [flang] [flang][OpenMP] Allow "Reason" messages to not have source locations (PR #187555)

via flang-commits flang-commits at lists.llvm.org
Thu Mar 19 11:53:21 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

When explanatory messages are generated there may be cases when there is no satisfactory source location to apply them to. This patch allows storing such messages without a source location.
The messages will be equipped with a source location at the time when they are attached to the main error message (usually it will be the same location as used for the main message).

Issue: https://github.com/llvm/llvm-project/issues/185287

---
Full diff: https://github.com/llvm/llvm-project/pull/187555.diff


3 Files Affected:

- (modified) flang/include/flang/Semantics/openmp-utils.h (+14-3) 
- (modified) flang/lib/Semantics/check-omp-loop.cpp (+9-9) 
- (modified) flang/lib/Semantics/openmp-utils.cpp (+14-2) 


``````````diff
diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index d7f46cbc7bd62..66bbbeb4ee0e7 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -23,6 +23,7 @@
 #include "flang/Semantics/tools.h"
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
 
 #include <optional>
 #include <string>
@@ -116,12 +117,22 @@ MaybeExpr MakeEvaluateExpr(const parser::OmpStylizedInstance &inp);
 struct Reason {
   parser::Messages msgs;
 
-  template <typename... Ts> Reason &Say(Ts &&...args) {
-    msgs.Say(std::forward<Ts>(args)...);
+  // Allow messages without a source location. They will acquire a location
+  // during AttachTo.
+  template <typename... Ts>
+  Reason &Say(parser::CharBlock source, Ts &&...args) {
+    auto &msg{msgs.Say(source, std::forward<Ts>(args)...)};
+    if (source.empty()) {
+      unsourced_.insert(&msg);
+    }
     return *this;
   }
   operator bool() const { return !msgs.empty(); }
-  parser::Message &AttachTo(parser::Message &msg);
+  parser::Message &AttachTo(parser::CharBlock source, parser::Message &msg);
+
+private:
+  // Set of messages without a source location.
+  llvm::DenseSet<const parser::Message *> unsourced_;
 };
 
 std::pair<std::optional<int64_t>, Reason> GetArgumentValueWithReason(
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 8f360daf4cfdc..f09b5f315dcc2 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -247,6 +247,7 @@ void OmpStructureChecker::CheckNestedConstruct(
   const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
   llvm::omp::Directive dir{beginSpec.DirId()};
   unsigned version{context_.langOptions().OpenMPVersion};
+  parser::CharBlock beginSource{beginSpec.DirName().source};
 
   // End-directive is not allowed in such cases:
   //   do 100 i = ...
@@ -257,7 +258,6 @@ void OmpStructureChecker::CheckNestedConstruct(
   auto &flags{std::get<parser::OmpDirectiveSpecification::Flags>(beginSpec.t)};
   if (flags.test(parser::OmpDirectiveSpecification::Flag::CrossesLabelDo)) {
     if (auto &endSpec{x.EndDir()}) {
-      parser::CharBlock beginSource{beginSpec.DirName().source};
       context_
           .Say(endSpec->DirName().source,
               "END %s directive is not allowed when the construct does not contain all loops that share a loop-terminating statement"_err_en_US,
@@ -297,12 +297,12 @@ void OmpStructureChecker::CheckNestedConstruct(
 
   if (std::optional<int64_t> numLoops{sequence.length()}) {
     if (*numLoops == 0) {
-      context_.Say(beginSpec.DirName().source,
+      context_.Say(beginSource,
           "This construct should contain a DO-loop or a loop-nest-generating OpenMP construct"_err_en_US);
     } else {
       auto assoc{llvm::omp::getDirectiveAssociation(dir)};
       if (*numLoops > 1 && assoc == llvm::omp::Association::LoopNest) {
-        context_.Say(beginSpec.DirName().source,
+        context_.Say(beginSource,
             "This construct applies to a loop nest, but has a loop sequence of "
             "length %" PRId64 ""_err_en_US,
             *numLoops);
@@ -310,12 +310,12 @@ void OmpStructureChecker::CheckNestedConstruct(
       if (assoc == llvm::omp::Association::LoopSeq) {
         if (auto requiredCount{GetRequiredCount(needFirst, needCount)}) {
           if (*requiredCount > 0 && *numLoops < *requiredCount) {
-            auto &msg{context_.Say(beginSpec.DirName().source,
+            auto &msg{context_.Say(beginSource,
                 "This construct requires a sequence of %" PRId64
                 " loops, but the loop sequence has a length of %" PRId64
                 ""_err_en_US,
                 *requiredCount, *numLoops)};
-            rangeReason.AttachTo(msg);
+            rangeReason.AttachTo(beginSource, msg);
           }
         }
       }
@@ -334,18 +334,18 @@ void OmpStructureChecker::CheckNestedConstruct(
     if (needDepth && haveDepth && *haveDepth > 0) {
       if (*needDepth > *haveDepth) {
         if (needPerfect) {
-          auto &msg{context_.Say(beginSpec.DirName().source,
+          auto &msg{context_.Say(beginSource,
               "This construct requires a perfect nest of depth %" PRId64
               ", but the associated nest is a perfect nest of depth %" PRId64
               ""_err_en_US,
               *needDepth, *haveDepth)};
-          depthReason.AttachTo(msg);
+          depthReason.AttachTo(beginSource, msg);
         } else {
-          auto &msg{context_.Say(beginSpec.DirName().source,
+          auto &msg{context_.Say(beginSource,
               "This construct requires a nest of depth %" PRId64
               ", but the associated nest has a depth of %" PRId64 ""_err_en_US,
               *needDepth, *haveDepth)};
-          depthReason.AttachTo(msg);
+          depthReason.AttachTo(beginSource, msg);
         }
       }
     }
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index e104096cb3af1..116d04cf93968 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -532,8 +532,20 @@ MaybeExpr MakeEvaluateExpr(const parser::OmpStylizedInstance &inp) {
       instance.u);
 }
 
-parser::Message &Reason::AttachTo(parser::Message &msg) {
-  msgs.AttachTo(msg);
+parser::Message &Reason::AttachTo(
+    parser::CharBlock source, parser::Message &msg) {
+  parser::Messages sourced;
+  for (auto &&msg : msgs.messages()) {
+    if (unsourced_.contains(&msg)) {
+      llvm::StringRef fmt{"%s"};
+      sourced.Say(source,
+          parser::MessageFixedText(fmt.data(), fmt.size(), msg.severity()),
+          msg.ToString());
+    } else {
+      sourced.Say(std::move(msg));
+    }
+  }
+  sourced.AttachTo(msg);
   return msg;
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/187555


More information about the flang-commits mailing list