diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -1092,7 +1092,9 @@ template ExtValue genval(const Fortran::evaluate::SetLength &x) { - TODO(getLoc(), "genval SetLength"); + mlir::Value newLenValue = genunbox(x.right()); + fir::ExtendedValue lhs = gen(x.left()); + return replaceScalarCharacterLength(lhs, newLenValue); } template diff --git a/flang/test/Lower/set-length.f90 b/flang/test/Lower/set-length.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/set-length.f90 @@ -0,0 +1,28 @@ +! Test evaluate::SetLength lowering (used to set a different length on a +! character storage around calls where the dummy and actual length differ). +! RUN: bbc -emit-fir -o - %s | FileCheck %s + + +subroutine takes_length_4(c) + character c(3)*4 + !do i = 1,3 + print *, c(i) + !enddo +end + +! CHECK-LABEL: func @_QPfoo( +subroutine foo(c) + character c(4)*3 + ! evaluate::Expr is: CALL s(%SET_LENGTH(c(1_8),4_8)) after semantics. + call takes_length_4(c(1)) +! CHECK: %[[VAL_2:.*]] = arith.constant 4 : i64 +! CHECK: %[[VAL_6:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.ref>>, i64) -> !fir.ref> +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>) -> !fir.ref> +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_2]] : (i64) -> index +! CHECK: %[[VAL_9:.*]] = fir.emboxchar %[[VAL_7]], %[[VAL_8]] : (!fir.ref>, index) -> !fir.boxchar<1> +! CHECK: fir.call @_QPtakes_length_4(%[[VAL_9]]) : (!fir.boxchar<1>) -> () +end subroutine + + character(3) :: c(4) = ["abc", "def", "ghi", "klm"] + call foo(c) +end