[flang-commits] [flang] f161964 - [flang] Better error recovery for bad submodules

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Wed Jun 29 11:35:02 PDT 2022


Author: Peter Klausler
Date: 2022-06-29T11:34:51-07:00
New Revision: f161964e1c00604941f276fe851aafabac7af5b6

URL: https://github.com/llvm/llvm-project/commit/f161964e1c00604941f276fe851aafabac7af5b6
DIFF: https://github.com/llvm/llvm-project/commit/f161964e1c00604941f276fe851aafabac7af5b6.diff

LOG: [flang] Better error recovery for bad submodules

When a submodule appears in a source file and the compiler can't find the
named ancestor module (and submodule, if one appears), crashes may occur
later due to the absence of a scope.  For better resilience, a dummy
ancestral scope should be generated within which the submodule scope
can be created.

Differential Revision: https://reviews.llvm.org/D128760

Added: 
    

Modified: 
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index ad3ede7a7d716..b3b7e306ae4a0 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2938,21 +2938,29 @@ void ModuleVisitor::AddAndCheckExplicitIntrinsicUse(
 
 bool ModuleVisitor::BeginSubmodule(
     const parser::Name &name, const parser::ParentIdentifier &parentId) {
-  auto &ancestorName{std::get<parser::Name>(parentId.t)};
-  auto &parentName{std::get<std::optional<parser::Name>>(parentId.t)};
+  const auto &ancestorName{std::get<parser::Name>(parentId.t)};
+  Scope *parentScope{nullptr};
   Scope *ancestor{FindModule(ancestorName, false /*not intrinsic*/)};
-  if (!ancestor) {
-    return false;
+  if (ancestor) {
+    if (const auto &parentName{
+            std::get<std::optional<parser::Name>>(parentId.t)}) {
+      parentScope = FindModule(*parentName, false /*not intrinsic*/, ancestor);
+    } else {
+      parentScope = ancestor;
+    }
   }
-  Scope *parentScope{parentName
-          ? FindModule(*parentName, false /*not intrinsic*/, ancestor)
-          : ancestor};
-  if (!parentScope) {
-    return false;
+  if (parentScope) {
+    PushScope(*parentScope);
+  } else {
+    // Error recovery: there's no ancestor scope, so create a dummy one to
+    // hold the submodule's scope.
+    SourceName dummyName{context().GetTempName(currScope())};
+    Symbol &dummySymbol{MakeSymbol(dummyName, Attrs{}, ModuleDetails{false})};
+    PushScope(Scope::Kind::Module, &dummySymbol);
+    parentScope = &currScope();
   }
-  PushScope(*parentScope); // submodule is hosted in parent
   BeginModule(name, true);
-  if (!ancestor->AddSubmodule(name.source, currScope())) {
+  if (ancestor && !ancestor->AddSubmodule(name.source, currScope())) {
     Say(name, "Module '%s' already has a submodule named '%s'"_err_en_US,
         ancestorName.source, name.source);
   }


        


More information about the flang-commits mailing list