[flang-commits] [flang] [flang] Lower procedure pointer components (PR #75453)
via flang-commits
flang-commits at lists.llvm.org
Mon Dec 18 00:29:49 PST 2023
================
@@ -165,20 +166,29 @@ fir::ExtendedValue Fortran::lower::genCallOpAndResult(
// will be used only if there is no explicit length in the local interface).
mlir::Value funcPointer;
mlir::Value charFuncPointerLength;
- if (const Fortran::semantics::Symbol *sym =
- caller.getIfIndirectCallSymbol()) {
- funcPointer = fir::getBase(converter.getSymbolExtendedValue(*sym, &symMap));
- if (!funcPointer)
- fir::emitFatalError(loc, "failed to find indirect call symbol address");
- if (fir::isCharacterProcedureTuple(funcPointer.getType(),
- /*acceptRawFunc=*/false))
- std::tie(funcPointer, charFuncPointerLength) =
- fir::factory::extractCharacterProcedureTuple(builder, loc,
- funcPointer);
- // Reference to a procedure pointer. Load its value, the address of the
- // procedure it points to.
- if (Fortran::semantics::IsProcedurePointer(sym))
- funcPointer = builder.create<fir::LoadOp>(loc, funcPointer);
+ if (const Fortran::evaluate::ProcedureDesignator *procDesignator =
+ caller.getIfIndirectCall()) {
+ if (std::optional<unsigned> passArg = caller.getPassArgIndex()) {
+ // Procedure pointer component call with PASS argument. To avoid
+ // "double" lowering of the ComponentRef, semantics only place the
+ // ComponentRef in the ActualArguments, not in the ProcedureDesignator (
+ // that is only the component symbol).
+ // Fetch the passed argument and addresses of its procedure pointer
+ // component.
+ mlir::Value passedArg = caller.getInputs()[*passArg];
+ funcPointer = Fortran::lower::derefPassProcPointerComponent(
+ loc, converter, *procDesignator, passedArg, symMap, stmtCtx);
+ } else {
+ Fortran::lower::SomeExpr expr{*procDesignator};
+ fir::ExtendedValue loweredProc =
+ converter.genExprAddr(loc, expr, stmtCtx);
+ funcPointer = fir::getBase(loweredProc);
----------------
jeanPerier wrote:
`genExprAddr` does it. For Pointers and Allocatables, the behavior of genExtAddr is to return the base address, not the address of the pointer/descriptor. So for procedure pointers, it will return the function address.
https://github.com/llvm/llvm-project/pull/75453
More information about the flang-commits
mailing list