[flang-commits] [flang] [Flang][OpenMP] Add checks for EXIT from associated loops (PR #91315)

Leandro Lupori via flang-commits flang-commits at lists.llvm.org
Tue May 7 05:38:51 PDT 2024


================
@@ -84,52 +84,69 @@ class OmpWorkshareBlockChecker {
   parser::CharBlock source_;
 };
 
-class OmpCycleChecker {
+class OmpCycleAndExitChecker {
 public:
-  OmpCycleChecker(SemanticsContext &context, std::int64_t cycleLevel)
-      : context_{context}, cycleLevel_{cycleLevel} {}
+  OmpCycleAndExitChecker(SemanticsContext &context, std::int64_t level)
+      : context_{context}, level_{level} {}
 
   template <typename T> bool Pre(const T &) { return true; }
   template <typename T> void Post(const T &) {}
 
   bool Pre(const parser::DoConstruct &dc) {
-    cycleLevel_--;
+    level_--;
     const auto &constructName{std::get<0>(std::get<0>(dc.t).statement.t)};
     if (constructName) {
       constructNamesAndLevels_.emplace(
-          constructName.value().ToString(), cycleLevel_);
+          constructName.value().ToString(), level_);
     }
     return true;
   }
 
+  void Post(const parser::DoConstruct &dc) { level_++; }
+
   bool Pre(const parser::CycleStmt &cyclestmt) {
     std::map<std::string, std::int64_t>::iterator it;
     bool err{false};
     if (cyclestmt.v) {
       it = constructNamesAndLevels_.find(cyclestmt.v->source.ToString());
       err = (it != constructNamesAndLevels_.end() && it->second > 0);
-    } else {
-      // If there is no label then the cycle statement is associated with the
-      // closest enclosing DO. Use its level for the checks.
-      err = cycleLevel_ > 0;
+    } else { // If there is no label then use the level of the last enclosing DO
+      err = level_ > 0;
     }
     if (err) {
-      context_.Say(*cycleSource_,
+      context_.Say(*source_,
           "CYCLE statement to non-innermost associated loop of an OpenMP DO "
           "construct"_err_en_US);
     }
     return true;
   }
 
+  bool Pre(const parser::ExitStmt &exitStmt) {
+    std::map<std::string, std::int64_t>::iterator it;
+    bool err{false};
+    if (exitStmt.v) {
+      it = constructNamesAndLevels_.find(exitStmt.v->source.ToString());
+      err = (it != constructNamesAndLevels_.end() && it->second >= 0);
+    } else { // If there is no label then use the level of the last enclosing DO
+      err = level_ >= 0;
+    }
+    if (err) {
+      context_.Say(*source_,
+          "EXIT statement to non-innermost associated loop of an OpenMP DO "
----------------
luporl wrote:

Since EXIT also can't be used in innermost associated loops, it would be better to change the error message to something like:
"EXIT statement terminating associated loop of an OpenMP DO construct"

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


More information about the flang-commits mailing list