[flang-commits] [flang] f4a5fb0 - [flang] Error checking for IBCLR/IBSET and ISHFT/SHIFT[ALR]

peter klausler via flang-commits flang-commits at lists.llvm.org
Thu Oct 7 13:51:28 PDT 2021


Author: peter klausler
Date: 2021-10-07T13:51:20-07:00
New Revision: f4a5fb0c5573477c2a597c3246513d8dba2f5e63

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

LOG: [flang] Error checking for IBCLR/IBSET and ISHFT/SHIFT[ALR]

Bit positions for the intrinsics IBCLR and IBSET and shift counts
for the intrinsics ISHFT/SHIFTA/SHIFTL/SHIFTR should be validated
when folding.

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

Added: 
    

Modified: 
    flang/lib/Evaluate/fold-integer.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 86fb46ba6094e..e8818082c5cf5 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -525,30 +525,30 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
   } else if (name == "iany") {
     return FoldBitReduction(
         context, std::move(funcRef), &Scalar<T>::IOR, Scalar<T>{});
-  } else if (name == "ibclr" || name == "ibset" || name == "ishft" ||
-      name == "shifta" || name == "shiftr" || name == "shiftl") {
-    // Second argument can be of any kind. However, it must be smaller or
-    // equal than BIT_SIZE. It can be converted to Int4 to simplify.
+  } else if (name == "ibclr" || name == "ibset") {
+    // Second argument can be of any kind. However, it must be smaller
+    // than BIT_SIZE. It can be converted to Int4 to simplify.
     auto fptr{&Scalar<T>::IBCLR};
-    if (name == "ibclr") { // done in fprt definition
+    if (name == "ibclr") { // done in fptr definition
     } else if (name == "ibset") {
       fptr = &Scalar<T>::IBSET;
-    } else if (name == "ishft") {
-      fptr = &Scalar<T>::ISHFT;
-    } else if (name == "shifta") {
-      fptr = &Scalar<T>::SHIFTA;
-    } else if (name == "shiftr") {
-      fptr = &Scalar<T>::SHIFTR;
-    } else if (name == "shiftl") {
-      fptr = &Scalar<T>::SHIFTL;
     } else {
       common::die("missing case to fold intrinsic function %s", name.c_str());
     }
     return FoldElementalIntrinsic<T, T, Int4>(context, std::move(funcRef),
-        ScalarFunc<T, T, Int4>(
-            [&fptr](const Scalar<T> &i, const Scalar<Int4> &pos) -> Scalar<T> {
-              return std::invoke(fptr, i, static_cast<int>(pos.ToInt64()));
-            }));
+        ScalarFunc<T, T, Int4>([&](const Scalar<T> &i,
+                                   const Scalar<Int4> &pos) -> Scalar<T> {
+          auto posVal{static_cast<int>(pos.ToInt64())};
+          if (posVal < 0) {
+            context.messages().Say(
+                "bit position for %s (%d) is negative"_err_en_US, name, posVal);
+          } else if (posVal >= i.bits) {
+            context.messages().Say(
+                "bit position for %s (%d) is not less than %d"_err_en_US, name,
+                posVal, i.bits);
+          }
+          return std::invoke(fptr, i, posVal);
+        }));
   } else if (name == "index" || name == "scan" || name == "verify") {
     if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0])}) {
       return std::visit(
@@ -610,6 +610,35 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
   } else if (name == "iparity") {
     return FoldBitReduction(
         context, std::move(funcRef), &Scalar<T>::IEOR, Scalar<T>{});
+  } else if (name == "ishft" || name == "shifta" || name == "shiftr" ||
+      name == "shiftl") {
+    // Second argument can be of any kind. However, it must be smaller or
+    // equal than BIT_SIZE. It can be converted to Int4 to simplify.
+    auto fptr{&Scalar<T>::ISHFT};
+    if (name == "ISHFT") { // done in fptr definition
+    } else if (name == "shifta") {
+      fptr = &Scalar<T>::SHIFTA;
+    } else if (name == "shiftr") {
+      fptr = &Scalar<T>::SHIFTR;
+    } else if (name == "shiftl") {
+      fptr = &Scalar<T>::SHIFTL;
+    } else {
+      common::die("missing case to fold intrinsic function %s", name.c_str());
+    }
+    return FoldElementalIntrinsic<T, T, Int4>(context, std::move(funcRef),
+        ScalarFunc<T, T, Int4>([&](const Scalar<T> &i,
+                                   const Scalar<Int4> &pos) -> Scalar<T> {
+          auto posVal{static_cast<int>(pos.ToInt64())};
+          if (posVal < 0) {
+            context.messages().Say(
+                "shift count for %s (%d) is negative"_err_en_US, name, posVal);
+          } else if (posVal > i.bits) {
+            context.messages().Say(
+                "shift count for %s (%d) is greater than %d"_err_en_US, name,
+                posVal, i.bits);
+          }
+          return std::invoke(fptr, i, posVal);
+        }));
   } else if (name == "lbound") {
     return LBOUND(context, std::move(funcRef));
   } else if (name == "leadz" || name == "trailz" || name == "poppar" ||


        


More information about the flang-commits mailing list