diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 76a51abfdc913..660de0b88c02f 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -822,6 +822,13 @@ class ScalarExprLowering { std::string name = converter.mangleName(*symbol); mlir::func::FuncOp func = Fortran::lower::getOrDeclareFunction(name, proc, converter); + // Abstract results require later rewrite of the function type. + // This currently does not happen inside GloalOps, causing LLVM + // IR verification failure. This helper is only here to catch these + // cases and emit a TODOs for now. + if (inInitializer && fir::hasAbstractResult(func.getFunctionType())) + TODO(converter.genLocation(symbol->name()), + "static description of non trivial procedure bindings"); funcPtr = builder.create(loc, func.getFunctionType(), builder.getSymbolRefAttr(name)); } diff --git a/flang/lib/Optimizer/Transforms/AbstractResult.cpp b/flang/lib/Optimizer/Transforms/AbstractResult.cpp index 1946ccdfd69f9..7dd821474698f 100644 --- a/flang/lib/Optimizer/Transforms/AbstractResult.cpp +++ b/flang/lib/Optimizer/Transforms/AbstractResult.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "PassDetail.h" +#include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRType.h" @@ -31,13 +32,6 @@ struct AbstractResultOptions { mlir::Value newArg; }; -static bool mustConvertCallOrFunc(mlir::FunctionType type) { - if (type.getNumResults() == 0) - return false; - auto resultType = type.getResult(0); - return resultType.isa(); -} - static mlir::Type getResultArgumentType(mlir::Type resultType, const AbstractResultOptions &options) { return llvm::TypeSwitch(resultType) @@ -223,7 +217,7 @@ class AbstractResultOpt : public fir::AbstractResultOptBase { // Convert function type itself if it has an abstract result auto funcTy = func.getFunctionType().cast(); - if (mustConvertCallOrFunc(funcTy)) { + if (hasAbstractResult(funcTy)) { func.setType(getNewFunctionType(funcTy, options)); unsigned zero = 0; if (!func.empty()) { @@ -252,11 +246,11 @@ class AbstractResultOpt : public fir::AbstractResultOptBase { mlir::func::FuncDialect>(); target.addIllegalOp(); target.addDynamicallyLegalOp([](fir::CallOp call) { - return !mustConvertCallOrFunc(call.getFunctionType()); + return !hasAbstractResult(call.getFunctionType()); }); target.addDynamicallyLegalOp([](fir::AddrOfOp addrOf) { if (auto funTy = addrOf.getType().dyn_cast()) - return !mustConvertCallOrFunc(funTy); + return !hasAbstractResult(funTy); return true; }); target.addDynamicallyLegalOp([](fir::DispatchOp dispatch) { @@ -264,8 +258,7 @@ class AbstractResultOpt : public fir::AbstractResultOptBase { return true; auto resultType = dispatch->getResult(0).getType(); if (resultType.isa()) { - mlir::emitError(dispatch.getLoc(), - "TODO: dispatchOp with abstract results"); + TODO(dispatch.getLoc(), "dispatchOp with abstract results"); return false; } return true;