Skip to content

[flang] fix ICE with ignore_tkr(tk) character in explicit interface #140885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions flang/lib/Lower/ConvertCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,6 @@ Fortran::lower::genCallOpAndResult(

// Deal with potential mismatches in arguments types. Passing an array to a
// scalar argument should for instance be tolerated here.
bool callingImplicitInterface = caller.canBeCalledViaImplicitInterface();
for (auto [fst, snd] : llvm::zip(caller.getInputs(), funcType.getInputs())) {
// When passing arguments to a procedure that can be called by implicit
// interface, allow any character actual arguments to be passed to dummy
Expand Down Expand Up @@ -518,10 +517,17 @@ Fortran::lower::genCallOpAndResult(
// Do not attempt any reboxing here that could break this.
bool legacyLowering =
!converter.getLoweringOptions().getLowerToHighLevelFIR();
// When dealing with a dummy character argument (fir.boxchar), the
// effective argument might be a non-character raw pointer. This may
// happen when calling an implicit interface that was previously called
// with a character argument, or when calling an explicit interface with
// an IgnoreTKR dummy character arguments. Allow creating a fir.boxchar
// from the raw pointer, which requires a non-trivial type conversion.
const bool allowCharacterConversions = true;
bool isVolatile = fir::isa_volatile_type(snd);
cast = builder.createVolatileCast(loc, isVolatile, fst);
cast = builder.convertWithSemantics(loc, snd, cast,
callingImplicitInterface,
allowCharacterConversions,
/*allowRebox=*/legacyLowering);
}
}
Expand Down Expand Up @@ -1446,6 +1452,8 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
// cause the fir.if results to be assumed-rank in case of OPTIONAL dummy,
// causing extra runtime costs due to the unknown runtime size of assumed-rank
// descriptors.
// For TKR dummy characters, the boxchar creation also happens later when
// creating the fir.call .
preparedDummy.dummy =
builder.createConvert(loc, dummyTypeWithActualRank, addr);
return preparedDummy;
Expand Down
17 changes: 17 additions & 0 deletions flang/test/Lower/HLFIR/ignore-type-f77-character.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ subroutine foo(c)
!dir$ ignore_tkr(tkrdm) c
end subroutine
end interface
interface
subroutine foo_requires_explicit_interface(c, i)
character(1)::c(*)
!dir$ ignore_tkr(tkrdm) c
integer, optional :: i
end subroutine
end interface
contains
subroutine test_normal()
character(1) :: c(10)
Expand All @@ -32,4 +39,14 @@ subroutine test_weird()
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()

subroutine test_requires_explicit_interface(x, i)
real :: x(10)
integer :: i
call foo_requires_explicit_interface(x, i)
end subroutine
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_requires_explicit_interface(
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
!CHECK: fir.call @_QPfoo_requires_explicit_interface(%[[VAL_6]], %{{.*}})
end module