diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index d37d51f6ec63..7378118cfef7 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -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 @@ -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); } } @@ -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; diff --git a/flang/test/Lower/HLFIR/ignore-type-f77-character.f90 b/flang/test/Lower/HLFIR/ignore-type-f77-character.f90 index 41dbf82d5789..6b2041a889e8 100644 --- a/flang/test/Lower/HLFIR/ignore-type-f77-character.f90 +++ b/flang/test/Lower/HLFIR/ignore-type-f77-character.f90 @@ -8,6 +8,13 @@ module test_char_tk !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) @@ -32,4 +39,14 @@ contains !CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref>) -> !fir.ref> !CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref>, index) -> !fir.boxchar<1> !CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath : (!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.ref> +!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref>, index) -> !fir.boxchar<1> +!CHECK: fir.call @_QPfoo_requires_explicit_interface(%[[VAL_6]], %{{.*}}) end module