diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1438,6 +1438,7 @@ void PreSpecificationConstruct(const parser::SpecificationConstruct &); void CreateGeneric(const parser::GenericSpec &); void FinishSpecificationPart(const std::list &); + void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt &); void CheckImports(); void CheckImport(const SourceName &, const SourceName &); void HandleCall(Symbol::Flag, const parser::Call &); @@ -6101,23 +6102,11 @@ } } currScope().InstantiateDerivedTypes(context()); - // Analyze the bodies of statement functions now that the symbol in this - // specification part have been fully declared and implicitly typed. for (const auto &decl : decls) { if (const auto *statement{std::get_if< parser::Statement>>( &decl.u)}) { - const parser::StmtFunctionStmt &stmtFunc{statement->statement.value()}; - if (Symbol * symbol{std::get(stmtFunc.t).symbol}) { - if (auto *details{symbol->detailsIf()}) { - if (auto expr{AnalyzeExpr(context(), - std::get>(stmtFunc.t))}) { - details->set_stmtFunction(std::move(*expr)); - } else { - context().SetError(*symbol); - } - } - } + AnalyzeStmtFunctionStmt(statement->statement.value()); } } // TODO: what about instantiations in BLOCK? @@ -6126,6 +6115,33 @@ CheckEquivalenceSets(); } +// Analyze the bodies of statement functions now that the symbols in this +// specification part have been fully declared and implicitly typed. +void ResolveNamesVisitor::AnalyzeStmtFunctionStmt( + const parser::StmtFunctionStmt &stmtFunc) { + Symbol *symbol{std::get(stmtFunc.t).symbol}; + if (!symbol || !symbol->has()) { + return; + } + auto &details{symbol->get()}; + auto expr{AnalyzeExpr( + context(), std::get>(stmtFunc.t))}; + if (!expr) { + context().SetError(*symbol); + return; + } + if (auto type{evaluate::DynamicType::From(*symbol)}) { + auto converted{ConvertToType(*type, std::move(*expr))}; + if (!converted) { + context().SetError(*symbol); + return; + } + details.set_stmtFunction(std::move(*converted)); + } else { + details.set_stmtFunction(std::move(*expr)); + } +} + void ResolveNamesVisitor::CheckImports() { auto &scope{currScope()}; switch (scope.GetImportKind()) { diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -111,6 +111,9 @@ } } os << (sep == '(' ? "()" : ")"); + if (x.stmtFunction_) { + os << " -> " << x.stmtFunction_->AsFortran(); + } return os; }