diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp index acfa64ac40e63..fdf6201c2284e 100644 --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -726,34 +726,31 @@ Expr> FoldIntrinsicFunction( const auto *lenCon{Folder(context).Folding(args[2])}; if (const auto *argCon{Folder(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(posIter->ToInt64())}; - auto lenVal{static_cast(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(posCon->values()[j % posCt].ToInt64()) + : 0}; + int lenVal{j < lenCt || lenCt == 1 + ? static_cast(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 be8700405673c..cbb05ffb72b57 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