[flang-commits] [flang] 6c5ba7c - [flang] Check constant POS/LEN arguments IBITS even when not both constant

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Jul 3 13:16:02 PDT 2023


Author: Peter Klausler
Date: 2023-07-03T13:04:14-07:00
New Revision: 6c5ba7cddfa2210e9ddb12ab6f016b84db9a8b23

URL: https://github.com/llvm/llvm-project/commit/6c5ba7cddfa2210e9ddb12ab6f016b84db9a8b23
DIFF: https://github.com/llvm/llvm-project/commit/6c5ba7cddfa2210e9ddb12ab6f016b84db9a8b23.diff

LOG: [flang] Check constant POS/LEN arguments IBITS even when not both constant

Apply compile-time checks to the values supplied for the POS and LEN
arguments of the IBITS intrinsic function even when only one of them
is a known constant.

Differential Revision: https://reviews.llvm.org/D154376

Added: 
    

Modified: 
    flang/lib/Evaluate/fold-integer.cpp
    flang/test/Evaluate/errors01.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index acfa64ac40e637..fdf6201c2284ed 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -726,34 +726,31 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
     const auto *lenCon{Folder<Int4>(context).Folding(args[2])};
     if (const auto *argCon{Folder<T>(context).Folding(args[0])};
         argCon && argCon->empty()) {
-    } else if (posCon && lenCon &&
-        (posCon->size() == 1 || lenCon->size() == 1 ||
-            posCon->size() == lenCon->size())) {
-      auto posIter{posCon->values().begin()};
-      auto lenIter{lenCon->values().begin()};
-      for (; posIter != posCon->values().end() &&
-           lenIter != lenCon->values().end();
-           ++posIter, ++lenIter) {
-        posIter = posIter == posCon->values().end() ? posCon->values().begin()
-                                                    : posIter;
-        lenIter = lenIter == lenCon->values().end() ? lenCon->values().begin()
-                                                    : lenIter;
-        auto posVal{static_cast<int>(posIter->ToInt64())};
-        auto lenVal{static_cast<int>(lenIter->ToInt64())};
+    } else {
+      std::size_t posCt{posCon ? posCon->size() : 0};
+      std::size_t lenCt{lenCon ? lenCon->size() : 0};
+      std::size_t n{std::max(posCt, lenCt)};
+      for (std::size_t j{0}; j < n; ++j) {
+        int posVal{j < posCt || posCt == 1
+                ? static_cast<int>(posCon->values()[j % posCt].ToInt64())
+                : 0};
+        int lenVal{j < lenCt || lenCt == 1
+                ? static_cast<int>(lenCon->values()[j % lenCt].ToInt64())
+                : 0};
         if (posVal < 0) {
           context.messages().Say(
-              "bit position for IBITS(POS=%jd,LEN=%jd) is negative"_err_en_US,
-              std::intmax_t{posVal}, std::intmax_t{lenVal});
+              "bit position for IBITS(POS=%jd) is negative"_err_en_US,
+              std::intmax_t{posVal});
           break;
         } else if (lenVal < 0) {
           context.messages().Say(
-              "bit length for IBITS(POS=%jd,LEN=%jd) is negative"_err_en_US,
-              std::intmax_t{posVal}, std::intmax_t{lenVal});
+              "bit length for IBITS(LEN=%jd) is negative"_err_en_US,
+              std::intmax_t{lenVal});
           break;
         } else if (posVal + lenVal > T::Scalar::bits) {
           context.messages().Say(
-              "IBITS(POS=%jd,LEN=%jd) must have POS+LEN no greater than %d"_err_en_US,
-              std::intmax_t{posVal}, std::intmax_t{lenVal}, T::Scalar::bits);
+              "IBITS() must have POS+LEN (>=%jd) no greater than %d"_err_en_US,
+              std::intmax_t{posVal + lenVal}, T::Scalar::bits);
           break;
         }
       }

diff  --git a/flang/test/Evaluate/errors01.f90 b/flang/test/Evaluate/errors01.f90
index be8700405673c1..cbb05ffb72b579 100644
--- a/flang/test/Evaluate/errors01.f90
+++ b/flang/test/Evaluate/errors01.f90
@@ -152,6 +152,17 @@ subroutine s13
     !CHECK: error: NCOPIES= argument to REPEAT() should be nonnegative, but is -666
     print *, repeat(' ', -666)
   end subroutine
+  subroutine s14(n)
+    integer, intent(in) :: n
+    !CHECK: error: bit position for IBITS(POS=-1) is negative
+    print *, ibits(0, -1, n)
+    !CHECK: error: bit length for IBITS(LEN=-1) is negative
+    print *, ibits(0, n, -1)
+    !CHECK: error: IBITS() must have POS+LEN (>=33) no greater than 32
+    print *, ibits(0, n, 33)
+    !CHECK: error: IBITS() must have POS+LEN (>=33) no greater than 32
+    print *, ibits(0, 33, n)
+  end
   subroutine warnings
     real, parameter :: ok1 = scale(0.0, 99999) ! 0.0
     real, parameter :: ok2 = scale(1.0, -99999) ! 0.0


        


More information about the flang-commits mailing list