Folding in the front end was replacing calls to LEN and dropping

arguments even in situations where the arguments are required to compute
the LEN value at runtime.

Add tests.

Differential Revision: https://reviews.llvm.org/D119373
This commit is contained in:
Eric Schweitz 2022-02-09 13:11:05 -08:00
parent 7aadf98d2b
commit 3915789503
2 changed files with 45 additions and 1 deletions

View File

@ -677,7 +677,11 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return std::visit(
[&](auto &kx) {
if (auto len{kx.LEN()}) {
return Fold(context, ConvertToType<T>(*std::move(len)));
if (IsScopeInvariantExpr(*len)) {
return Fold(context, ConvertToType<T>(*std::move(len)));
} else {
return Expr<T>{std::move(funcRef)};
}
} else {
return Expr<T>{std::move(funcRef)};
}

View File

@ -76,4 +76,44 @@ subroutine lbound_test(x, n, m)
!CHECK: PRINT *, 1_4
print *, lbound(returns_array_3(), dim=1)
end subroutine
!CHECK: len_test
subroutine len_test(a,b, c, d, e, n, m)
character(*), intent(in) :: a
character(*) :: b
external b
character(10), intent(in) :: c
character(10) :: d
external d
integer, intent(in) :: n, m
character(n), intent(in) :: e
!CHECK: PRINT *, int(a%len,kind=4)
print *, len(a)
!CHECK: PRINT *, 5_4
print *, len(a(1:5))
!CHECK: PRINT *, len(b(a))
print *, len(b(a))
!CHECK: PRINT *, len(b(a)//a)
print *, len(b(a) // a)
!CHECK: PRINT *, 10_4
print *, len(c)
!CHECK: PRINT *, len(c(int(i,kind=8):int(j,kind=8)))
print *, len(c(i:j))
!CHECK: PRINT *, 5_4
print *, len(c(1:5))
!CHECK: PRINT *, 10_4
print *, len(d(c))
!CHECK: PRINT *, 20_4
print *, len(d(c) // c)
!CHECK: PRINT *, 0_4
print *, len(a(10:4))
!CHECK: PRINT *, int(max(0_8,int(m,kind=8)-int(n,kind=8)+1_8),kind=4)
print *, len(a(n:m))
!CHECK: PRINT *, len(b(a(int(n,kind=8):int(m,kind=8))))
print *, len(b(a(n:m)))
!CHECK: PRINT *, int(max(0_8,max(0_8,int(n,kind=8))-4_8+1_8),kind=4)
print *, len(e(4:))
end subroutine len_test
end module