Skip to content

Commit

Permalink
[flang] Prevent character length setting with dangling ac-do-variable.
Browse files Browse the repository at this point in the history
This fixes LEN inquiry on array constructors where the length
expression includes references to the ac-do-variable.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D150149
  • Loading branch information
vzakhari committed May 8, 2023
1 parent 6fe4621 commit c8b50b8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
15 changes: 14 additions & 1 deletion flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,20 @@ class ArrayConstructorContext {
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));
}
}
Expand Down
3 changes: 3 additions & 0 deletions flang/test/Evaluate/rewrite01.f90
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,13 @@ function return_allocatable()
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

0 comments on commit c8b50b8

Please sign in to comment.