Skip to content

Commit

Permalink
[flang] sanitize set_length in lowering (#80412)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jeanPerier committed Feb 2, 2024
1 parent c66cedb commit 7a4570a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
5 changes: 4 additions & 1 deletion flang/lib/Lower/ConvertExprToHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,8 +1219,11 @@ struct BinaryOp<Fortran::evaluate::SetLength<KIND>> {
fir::FirOpBuilder &builder, const Op &,
hlfir::Entity string,
hlfir::Entity length) {
// The input length may be a user input and needs to be sanitized as per
// Fortran 2018 7.4.4.2 point 5.
mlir::Value safeLength = fir::factory::genMaxWithZero(builder, loc, length);
return hlfir::EntityWithAttributes{
builder.create<hlfir::SetLengthOp>(loc, string, length)};
builder.create<hlfir::SetLengthOp>(loc, string, safeLength)};
}
static void
genResultTypeParams(mlir::Location, fir::FirOpBuilder &, hlfir::Entity,
Expand Down
14 changes: 14 additions & 0 deletions flang/test/Lower/HLFIR/array-ctor-character.f90
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,17 @@ subroutine takes_char(c)
print *, "expect: abcdef"
call test_dynamic_length()
end

subroutine test_set_length_sanitize(i, c1)
integer(8) :: i
character(*) :: c1
call takes_char([character(len=i):: c1])
end subroutine
! CHECK-LABEL: func.func @_QPtest_set_length_sanitize(
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ec1
! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}Ei
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_25]], %[[VAL_26]] : i64
! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i64
! CHECK: %[[VAL_29:.*]] = hlfir.set_length %[[VAL_6]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>

0 comments on commit 7a4570a

Please sign in to comment.