[flang-commits] [PATCH] D154376: [flang] Check constant POS/LEN arguments IBITS even when not both constant
Peter Klausler via Phabricator via flang-commits
flang-commits at lists.llvm.org
Mon Jul 3 10:29:47 PDT 2023
klausler created this revision.
klausler added a reviewer: PeteSteinfeld.
klausler added a project: Flang.
Herald added subscribers: sunshaoce, jdoerfert.
Herald added a project: All.
klausler requested review of this revision.
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.
https://reviews.llvm.org/D154376
Files:
flang/lib/Evaluate/fold-integer.cpp
flang/test/Evaluate/errors01.f90
Index: flang/test/Evaluate/errors01.f90
===================================================================
--- flang/test/Evaluate/errors01.f90
+++ flang/test/Evaluate/errors01.f90
@@ -152,6 +152,17 @@
!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
Index: flang/lib/Evaluate/fold-integer.cpp
===================================================================
--- flang/lib/Evaluate/fold-integer.cpp
+++ flang/lib/Evaluate/fold-integer.cpp
@@ -726,34 +726,31 @@
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;
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154376.536839.patch
Type: text/x-patch
Size: 3686 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230703/c54d76c3/attachment-0001.bin>
More information about the flang-commits
mailing list