[flang] allow alternate return indicators
authorpeter klausler <pklausler@nvidia.com>
Mon, 3 Jun 2019 20:36:47 +0000 (13:36 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 4 Jun 2019 20:37:20 +0000 (13:37 -0700)
Original-commit: flang-compiler/f18@a04150a4f96f251e7b4a940877ef421a60c1a163
Reviewed-on: https://github.com/flang-compiler/f18/pull/477
Tree-same-pre-rewrite: false

flang/lib/semantics/resolve-names.cc
flang/lib/semantics/symbol.h

index 4c86783..5f467f2 100644 (file)
@@ -891,7 +891,9 @@ public:
   bool Pre(const parser::WhereConstructStmt &x) { return CheckDef(x.t); }
   bool Pre(const parser::ForallConstructStmt &x) { return CheckDef(x.t); }
   bool Pre(const parser::CriticalStmt &x) { return CheckDef(x.t); }
-  bool Pre(const parser::LabelDoStmt &x) { common::die("should not happen"); }
+  bool Pre(const parser::LabelDoStmt &x) {
+    return false;  // error recovery
+  }
   bool Pre(const parser::NonLabelDoStmt &x) { return CheckDef(x.t); }
   bool Pre(const parser::IfThenStmt &x) { return CheckDef(x.t); }
   bool Pre(const parser::SelectCaseStmt &x) { return CheckDef(x.t); }
@@ -1567,6 +1569,7 @@ void ScopeHandler::PushScope(Scope &scope) {
 void ScopeHandler::PopScope() {
   // Entities that are not yet classified as objects or procedures are now
   // assumed to be objects.
+  // TODO: Statement functions
   for (auto &pair : currScope()) {
     ConvertToObjectEntity(*pair.second);
   }
@@ -2259,10 +2262,12 @@ void SubprogramVisitor::Post(const parser::SubroutineStmt &stmt) {
   const auto &name{std::get<parser::Name>(stmt.t)};
   auto &details{PostSubprogramStmt(name)};
   for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) {
-    const parser::Name *dummyName = std::get_if<parser::Name>(&dummyArg.u);
-    CHECK(dummyName != nullptr && "TODO: alternate return indicator");
-    Symbol &dummy{MakeSymbol(*dummyName, EntityDetails(true))};
-    details.add_dummyArg(dummy);
+    if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
+      Symbol &dummy{MakeSymbol(*dummyName, EntityDetails(true))};
+      details.add_dummyArg(dummy);
+    } else {
+      details.add_alternateReturn();
+    }
   }
 }
 
index bd5f61e..21b05b4 100644 (file)
@@ -75,11 +75,12 @@ public:
   }
   const std::list<Symbol *> &dummyArgs() const { return dummyArgs_; }
   void add_dummyArg(Symbol &symbol) { dummyArgs_.push_back(&symbol); }
+  void add_alternateReturn() { dummyArgs_.push_back(nullptr); }
 
 private:
   bool isInterface_{false};  // true if this represents an interface-body
   MaybeExpr bindName_;
-  std::list<Symbol *> dummyArgs_;
+  std::list<Symbol *> dummyArgs_;  // nullptr -> alternate return indicator
   Symbol *result_{nullptr};
   friend std::ostream &operator<<(std::ostream &, const SubprogramDetails &);
 };