Skip to content

Commit 49cb159

Browse files
authored
[flang][hlfir] Cast actual cst len character to stmt func dummy type (#68598)
When calling a statement function with a character actual argument with a constant length mismatching the dummy length, HLFIR lowering created an hlfir.declare with the actual argument length for the dummy, causing bugs when lowering the statement function expression. Ensure character dummies are always cast to the dummy type when lowering dummy declarations.
1 parent 37a8cfb commit 49cb159

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,13 +1947,15 @@ void Fortran::lower::mapSymbolAttributes(
19471947
if (ba.isChar()) {
19481948
if (arg) {
19491949
assert(!preAlloc && "dummy cannot be pre-allocated");
1950-
if (arg.getType().isa<fir::BoxCharType>()) {
1950+
if (arg.getType().isa<fir::BoxCharType>())
19511951
std::tie(addr, len) = charHelp.createUnboxChar(arg);
1952-
// Ensure proper type is given to array/scalar that transited via
1953-
// fir.boxchar arg.
1954-
mlir::Type castTy = builder.getRefType(converter.genType(var));
1955-
addr = builder.createConvert(loc, castTy, addr);
1956-
}
1952+
else if (!addr)
1953+
addr = arg;
1954+
// Ensure proper type is given to array/scalar that was transmitted as a
1955+
// fir.boxchar arg or is a statement function actual argument with
1956+
// a different length than the dummy.
1957+
mlir::Type castTy = builder.getRefType(converter.genType(var));
1958+
addr = builder.createConvert(loc, castTy, addr);
19571959
}
19581960
if (std::optional<int64_t> cstLen = ba.getCharLenConst()) {
19591961
// Static length

flang/test/Lower/HLFIR/statement-functions.f90

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,17 @@ subroutine char_test(c, n)
3333
! CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_13]]#0 typeparams %[[VAL_17]] {uniq_name = "_QFchar_testFstmt_funcEchar_stmt_func_dummy_arg"} : (!fir.ref<!fir.char<1,?>>, i32) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
3434
! CHECK: %[[VAL_19:.*]] = arith.constant 10 : i64
3535
! CHECK: %[[VAL_20:.*]] = hlfir.set_length %[[VAL_18]]#0 len %[[VAL_19]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,10>>
36+
37+
subroutine char_test2(c)
38+
character(10) :: c
39+
character(5) :: c_stmt_func
40+
character(*), parameter :: padding = "padding"
41+
character(len(c_stmt_func)+len(padding)) :: stmt_func
42+
stmt_func(c_stmt_func) = c_stmt_func // padding
43+
call test(stmt_func(c))
44+
end subroutine
45+
! CHECK-LABEL: func.func @_QPchar_test2(
46+
! CHECK: %[[C:.*]]:2 = hlfir.declare %1 typeparams %c10 {uniq_name = "_QFchar_test2Ec"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
47+
! CHECK: %[[CAST:.*]] = fir.convert %[[C]]#0 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,5>>
48+
! CHECK: %[[C_STMT_FUNC:.*]]:2 = hlfir.declare %[[CAST]] typeparams %c5{{.*}} {uniq_name = "_QFchar_test2Fstmt_funcEc_stmt_func"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
49+
! CHECK: hlfir.concat %[[C_STMT_FUNC]]#0, %{{.*}} len %{{.*}} : (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,7>>, index) -> !hlfir.expr<!fir.char<1,12>>

0 commit comments

Comments
 (0)