[PATCH] D84452: [flang] Implicitly convert result of statement function

Tim Keith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 23 11:17:08 PDT 2020


tskeith created this revision.
tskeith added reviewers: klausler, PeteSteinfeld.
tskeith added a project: Flang.
Herald added a reviewer: jdoerfert.
Herald added a reviewer: DavidTruby.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The result of a statement function may require an implicit conversion
to match its result type. Add that to the expression that represents
the statement function body in SubprogramDetails.

Extract the analysis of that expression into a separate function.

Dump the statement function expression as part of the dump of
SubprogramDetails.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84452

Files:
  flang/lib/Semantics/resolve-names.cpp
  flang/lib/Semantics/symbol.cpp


Index: flang/lib/Semantics/symbol.cpp
===================================================================
--- flang/lib/Semantics/symbol.cpp
+++ flang/lib/Semantics/symbol.cpp
@@ -111,6 +111,9 @@
     }
   }
   os << (sep == '(' ? "()" : ")");
+  if (x.stmtFunction_) {
+    os << " -> " << x.stmtFunction_->AsFortran();
+  }
   return os;
 }
 
Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ 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<parser::DeclarationConstruct> &);
+  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<common::Indirection<parser::StmtFunctionStmt>>>(
             &decl.u)}) {
-      const parser::StmtFunctionStmt &stmtFunc{statement->statement.value()};
-      if (Symbol * symbol{std::get<parser::Name>(stmtFunc.t).symbol}) {
-        if (auto *details{symbol->detailsIf<SubprogramDetails>()}) {
-          if (auto expr{AnalyzeExpr(context(),
-                  std::get<parser::Scalar<parser::Expr>>(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,34 @@
   CheckEquivalenceSets();
 }
 
+// Analyze the bodies of statement functions now that the symbol in this
+// specification part have been fully declared and implicitly typed.
+void ResolveNamesVisitor::AnalyzeStmtFunctionStmt(
+    const parser::StmtFunctionStmt &stmtFunc) {
+  Symbol *symbol{std::get<parser::Name>(stmtFunc.t).symbol};
+  if (!symbol || !symbol->has<SubprogramDetails>()) {
+    return;
+  }
+  auto &details{symbol->get<SubprogramDetails>()};
+  auto expr{AnalyzeExpr(
+      context(), std::get<parser::Scalar<parser::Expr>>(stmtFunc.t))};
+  if (!expr) {
+    context().SetError(*symbol);
+    return;
+  }
+  if (auto type{evaluate::DynamicType::From(*symbol)};
+      type && type != expr->GetType()) {
+    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()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84452.280204.patch
Type: text/x-patch
Size: 3149 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200723/6d113682/attachment.bin>


More information about the llvm-commits mailing list