[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