[flang-commits] [flang] [flang] Disallow references to some IEEE procedures in DO CONCURRENT (PR #102082)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Aug 5 16:49:42 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/102082

There's a numbered constraint that prohibits calls to some IEEE arithmetic and exception procedures within the body of a DO CONCURRENT construct.  Clean up the implementation to catch missing cases.

>From ae29d2e40c0e0b1bc307a146ddd282c3940b90e3 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 5 Aug 2024 16:47:31 -0700
Subject: [PATCH] [flang] Disallow references to some IEEE procedures in DO
 CONCURRENT

There's a numbered constraint that prohibits calls to some IEEE
arithmetic and exception procedures within the body of a DO CONCURRENT
construct.  Clean up the implementation to catch missing cases.
---
 flang/lib/Semantics/check-do-forall.cpp    | 44 ++++++++++++----------
 flang/module/__fortran_ieee_exceptions.f90 |  2 +-
 flang/test/Semantics/doconcurrent01.f90    | 20 ++++++----
 3 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp
index 34225cd406192..dc4dd9ab3900f 100644
--- a/flang/lib/Semantics/check-do-forall.cpp
+++ b/flang/lib/Semantics/check-do-forall.cpp
@@ -286,19 +286,32 @@ class DoConcurrentBodyEnforce {
         .Attach(doConcurrentSourcePosition_, GetEnclosingDoMsg());
   }
 
-  // C1139: call to impure procedure and ...
-  // C1141: cannot call ieee_get_flag, ieee_[gs]et_halting_mode
-  // It's not necessary to check the ieee_get* procedures because they're
-  // not pure, and impure procedures are caught by checks for constraint C1139
+  // C1145, C1146: cannot call ieee_[gs]et_flag, ieee_[gs]et_halting_mode,
+  // ieee_[gs]et_status, ieee_set_rounding_mode, or ieee_set_underflow_mode
   void Post(const parser::ProcedureDesignator &procedureDesignator) {
     if (auto *name{std::get_if<parser::Name>(&procedureDesignator.u)}) {
-      if (name->symbol &&
-          fromScope(*name->symbol, "__fortran_ieee_exceptions"s)) {
-        if (name->source == "ieee_set_halting_mode") {
-          SayWithDo(context_, currentStatementSourcePosition_,
-              "IEEE_SET_HALTING_MODE is not allowed in DO "
-              "CONCURRENT"_err_en_US,
-              doConcurrentSourcePosition_);
+      if (name->symbol) {
+        const Symbol &ultimate{name->symbol->GetUltimate()};
+        const Scope &scope{ultimate.owner()};
+        if (const Symbol * module{scope.IsModule() ? scope.symbol() : nullptr};
+            module &&
+            (module->name() == "__fortran_ieee_arithmetic" ||
+                module->name() == "__fortran_ieee_exceptions")) {
+          std::string s{ultimate.name().ToString()};
+          static constexpr const char *badName[]{"ieee_get_flag",
+              "ieee_set_flag", "ieee_get_halting_mode", "ieee_set_halting_mode",
+              "ieee_get_status", "ieee_set_status", "ieee_set_rounding_mode",
+              "ieee_set_underflow_mode", nullptr};
+          for (std::size_t j{0}; badName[j]; ++j) {
+            if (s.find(badName[j]) != s.npos) {
+              context_
+                  .Say(name->source,
+                      "'%s' may not be called in DO CONCURRENT"_err_en_US,
+                      badName[j])
+                  .Attach(doConcurrentSourcePosition_, GetEnclosingDoMsg());
+              break;
+            }
+          }
         }
       }
     }
@@ -319,15 +332,6 @@ class DoConcurrentBodyEnforce {
   }
 
 private:
-  bool fromScope(const Symbol &symbol, const std::string &moduleName) {
-    if (symbol.GetUltimate().owner().IsModule() &&
-        symbol.GetUltimate().owner().GetName().value().ToString() ==
-            moduleName) {
-      return true;
-    }
-    return false;
-  }
-
   std::set<parser::Label> labels_;
   parser::CharBlock currentStatementSourcePosition_;
   SemanticsContext &context_;
diff --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang/module/__fortran_ieee_exceptions.f90
index 810a2b0e400f2..cebd604520181 100644
--- a/flang/module/__fortran_ieee_exceptions.f90
+++ b/flang/module/__fortran_ieee_exceptions.f90
@@ -129,7 +129,7 @@ end subroutine ieee_set_modes_0
   public :: ieee_set_modes
 
   interface ieee_set_status
-    subroutine ieee_set_status_0(status)
+    pure subroutine ieee_set_status_0(status)
       import ieee_status_type
       type(ieee_status_type), intent(in) :: status
     end subroutine ieee_set_status_0
diff --git a/flang/test/Semantics/doconcurrent01.f90 b/flang/test/Semantics/doconcurrent01.f90
index 7c13a26814e5b..9bb2b45376835 100644
--- a/flang/test/Semantics/doconcurrent01.f90
+++ b/flang/test/Semantics/doconcurrent01.f90
@@ -48,18 +48,22 @@ subroutine do_concurrent_test2(i,j,n,flag)
     change team (j)
 !ERROR: An image control statement is not allowed in DO CONCURRENT
       critical
-        call ieee_get_status(status) ! ok
-!ERROR: IEEE_SET_HALTING_MODE is not allowed in DO CONCURRENT
-        call ieee_set_halting_mode(flag, halting)
       end critical
     end team
 !ERROR: ADVANCE specifier is not allowed in DO CONCURRENT
     write(*,'(a35)',advance='no')
-  end do
-
-! The following is OK
-  do concurrent (i = 1:n)
-        call ieee_set_flag(flag, flagValue)
+!ERROR: 'ieee_get_status' may not be called in DO CONCURRENT
+    call ieee_get_status(status)
+!ERROR: 'ieee_set_status' may not be called in DO CONCURRENT
+    call ieee_set_status(status)
+!ERROR: 'ieee_get_halting_mode' may not be called in DO CONCURRENT
+    call ieee_get_halting_mode(flag, halting)
+!ERROR: 'ieee_set_halting_mode' may not be called in DO CONCURRENT
+    call ieee_set_halting_mode(flag, halting)
+!ERROR: 'ieee_get_flag' may not be called in DO CONCURRENT
+    call ieee_get_flag(flag, flagValue)
+!ERROR: 'ieee_set_flag' may not be called in DO CONCURRENT
+    call ieee_set_flag(flag, flagValue)
   end do
 end subroutine do_concurrent_test2
 



More information about the flang-commits mailing list