[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