[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