diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index f60cdbb690e7c..d8271b1f14635 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -922,7 +922,8 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( // Handle procedure arguments (procedure pointers should go through // prepareProcedurePointerActualArgument). if (hlfir::isFortranProcedureValue(dummyType)) { - // Procedure pointer actual to procedure dummy. + // Procedure pointer or function returns procedure pointer actual to + // procedure dummy. if (actual.isProcedurePointer()) { actual = hlfir::derefPointersAndAllocatables(loc, builder, actual); return PreparedDummyArgument{actual, /*cleanups=*/{}}; @@ -931,7 +932,11 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( assert(actual.isProcedure()); // Do nothing if this is a procedure argument. It is already a // fir.boxproc/fir.tuple as it should. - if (actual.getType() != dummyType) + if (!actual.getType().isa() && + actual.getType() != dummyType) + // The actual argument may be a procedure that returns character (a + // fir.tuple) while the dummy is not. Extract the tuple + // in that case. actual = fixProcedureDummyMismatch(loc, builder, actual, dummyType); return PreparedDummyArgument{actual, /*cleanups=*/{}}; }