Skip to content

Commit 7a4570a

Browse files
authored
[flang] sanitize set_length in lowering (#80412)
In fortran, it is possible to give a negative "i" in "character(i)" in which case the standard says the length is zero. So the length must be sanitized as max(0, user_input) in lowering. This is already done when lowering specification parts, but was not done when "character(i)" appears in array constructors. Sanitize the length when lowering SetLength in lowering. Fixes #80270
1 parent c66cedb commit 7a4570a

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,8 +1219,11 @@ struct BinaryOp<Fortran::evaluate::SetLength<KIND>> {
12191219
fir::FirOpBuilder &builder, const Op &,
12201220
hlfir::Entity string,
12211221
hlfir::Entity length) {
1222+
// The input length may be a user input and needs to be sanitized as per
1223+
// Fortran 2018 7.4.4.2 point 5.
1224+
mlir::Value safeLength = fir::factory::genMaxWithZero(builder, loc, length);
12221225
return hlfir::EntityWithAttributes{
1223-
builder.create<hlfir::SetLengthOp>(loc, string, length)};
1226+
builder.create<hlfir::SetLengthOp>(loc, string, safeLength)};
12241227
}
12251228
static void
12261229
genResultTypeParams(mlir::Location, fir::FirOpBuilder &, hlfir::Entity,

flang/test/Lower/HLFIR/array-ctor-character.f90

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,17 @@ subroutine takes_char(c)
8686
print *, "expect: abcdef"
8787
call test_dynamic_length()
8888
end
89+
90+
subroutine test_set_length_sanitize(i, c1)
91+
integer(8) :: i
92+
character(*) :: c1
93+
call takes_char([character(len=i):: c1])
94+
end subroutine
95+
! CHECK-LABEL: func.func @_QPtest_set_length_sanitize(
96+
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ec1
97+
! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}Ei
98+
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i64>
99+
! CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64
100+
! CHECK: %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_25]], %[[VAL_26]] : i64
101+
! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i64
102+
! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_6]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>

0 commit comments

Comments
 (0)