diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -115,6 +115,17 @@ } ++passArgIdx; } + if (!passArg) + return passArg; + // Take into account result inserted as arguments. + if (std::optional::PassedEntity> + resultArg = getPassedResult()) { + if (resultArg->passBy == PassEntityBy::AddressAndLength) + passArg = *passArg + 2; + else if (resultArg->passBy == PassEntityBy::BaseAddress) + passArg = *passArg + 1; + } return passArg; } diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -18,6 +18,12 @@ real, pointer :: rp(:) => null() end type + type c1 + character(2) :: tmp = 'c1' + contains + procedure :: get_tmp + end type + contains ! Test correct access to polymorphic entity component. @@ -140,4 +146,23 @@ ! CHECK: fir.store %[[REBOX_TO_UP]] to %[[P]] : !fir.ref>>> ! CHECK: return +! Test that the fir.dispatch operation is created with the correct pass object +! and the pass_arg_pos attribute is incremented correctly when character +! function result is added as argument. + + function get_tmp(this) + class(c1) :: this + character(2) :: get_tmp + get_tmp = this%tmp + end function + + subroutine call_get_tmp(c) + class(c1) :: c + print*, c%get_tmp() + end subroutine + +! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_get_tmp( +! CHECK-SAME: %[[ARG0:.*]]: !fir.class}>> {fir.bindc_name = "c"}) { +! CHECK: %{{.*}} = fir.dispatch "get_tmp"(%[[ARG0]] : !fir.class}>>) (%{{.*}}, %{{.*}}, %[[ARG0]] : !fir.ref>, index, !fir.class}>>) -> !fir.boxchar<1> {pass_arg_pos = 2 : i32} + end module