ArrayConstructor<T> result{MakeSpecific<T>(std::move(values_))};
if constexpr (T::category == TypeCategory::Character) {
if (auto len{type_->LEN()}) {
- if (IsConstantExpr(*len)) {
+ // The ac-do-variables may be treated as constant expressions,
+ // if some conditions on ac-implied-do-control hold (10.1.12 (12)).
+ // At the same time, they may be treated as constant expressions
+ // only in the context of the ac-implied-do, but setting
+ // the character length here may result in complete elimination
+ // of the ac-implied-do. For example:
+ // character(10) :: c
+ // ... len([(c(i:i), integer(8)::i = 1,4)])
+ // would be evaulated into:
+ // ... int(max(0_8,i-i+1_8),kind=4)
+ // with a dangling reference to the ac-do-variable.
+ // Prevent this by checking for the ac-do-variable references
+ // in the 'len' expression.
+ if (!ContainsAnyImpliedDoIndex(*len) && IsConstantExpr(*len)) {
result.set_LEN(std::move(*len));
}
}
subroutine array_ctor_implied_do_index(x, j)
integer :: x(:)
integer(8) :: j
+ character(10) :: c
!CHECK: PRINT *, size([INTEGER(4)::(x(1_8:i:1_8),INTEGER(8)::i=1_8,2_8,1_8)])
print *, size([(x(1:i), integer(8)::i=1,2)])
!CHECK: PRINT *, int(0_8+2_8*(0_8+max((j-1_8+1_8)/1_8,0_8)),kind=4)
print *, size([(x(1:j), integer(8)::i=1,2)])
+ !CHECK: PRINT *, len([(c(i:i),INTEGER(8)::i=1_8,4_8,1_8)])
+ print *, len([(c(i:i), integer(8)::i = 1,4)])
end subroutine
end module