[flang-commits] [flang] f4bb211 - [flang] Fix crash from PDT component init in module file

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Apr 26 10:49:14 PDT 2022


Author: Peter Klausler
Date: 2022-04-26T10:49:05-07:00
New Revision: f4bb211a3b1600bd56edf17479f77f86ab402d7b

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

LOG: [flang] Fix crash from PDT component init in module file

Semantics now needs to preserve the parse trees from module files,
in case they contain parameterized derived type definitions with
component initializers that may require re-analysis during PDT
instantiation.  Save them in the SemanticsContext.

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

Added: 
    

Modified: 
    flang/include/flang/Semantics/semantics.h
    flang/lib/Semantics/mod-file.cpp
    flang/lib/Semantics/semantics.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h
index 6bd194fdfc03e..b64420eb20e4a 100644
--- a/flang/include/flang/Semantics/semantics.h
+++ b/flang/include/flang/Semantics/semantics.h
@@ -195,6 +195,10 @@ class SemanticsContext {
   void UseFortranBuiltinsModule();
   const Scope *GetBuiltinsScope() const { return builtinsScope_; }
 
+  // Saves a module file's parse tree so that it remains available
+  // during semantics.
+  parser::Program &SaveParseTree(parser::Program &&);
+
 private:
   void CheckIndexVarRedefine(
       const parser::CharBlock &, const Symbol &, parser::MessageFixedText &&);
@@ -226,6 +230,7 @@ class SemanticsContext {
   UnorderedSymbolSet errorSymbols_;
   std::set<std::string> tempNames_;
   const Scope *builtinsScope_{nullptr}; // module __Fortran_builtins
+  std::list<parser::Program> modFileParseTrees_;
 };
 
 class Semantics {

diff  --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 212e4c5d2f059..d7e6efcb3b398 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -970,13 +970,14 @@ Scope *ModFileReader::Read(const SourceName &name,
   }
   llvm::raw_null_ostream NullStream;
   parsing.Parse(NullStream);
-  auto &parseTree{parsing.parseTree()};
+  std::optional<parser::Program> &parsedProgram{parsing.parseTree()};
   if (!parsing.messages().empty() || !parsing.consumedWholeFile() ||
-      !parseTree) {
+      !parsedProgram) {
     Say(name, ancestorName, "Module file is corrupt: %s"_err_en_US,
         sourceFile->path());
     return nullptr;
   }
+  parser::Program &parseTree{context_.SaveParseTree(std::move(*parsedProgram))};
   Scope *parentScope; // the scope this module/submodule goes into
   if (!isIntrinsic.has_value()) {
     for (const auto &dir : context_.intrinsicModuleDirectories()) {
@@ -991,7 +992,7 @@ Scope *ModFileReader::Read(const SourceName &name,
                                               : context_.globalScope()};
   if (!ancestor) {
     parentScope = &topScope;
-  } else if (std::optional<SourceName> parent{GetSubmoduleParent(*parseTree)}) {
+  } else if (std::optional<SourceName> parent{GetSubmoduleParent(parseTree)}) {
     parentScope = Read(*parent, false /*not intrinsic*/, ancestor, silent);
   } else {
     parentScope = ancestor;
@@ -1002,7 +1003,7 @@ Scope *ModFileReader::Read(const SourceName &name,
   }
   Symbol &modSymbol{*pair.first->second};
   modSymbol.set(Symbol::Flag::ModFile);
-  ResolveNames(context_, *parseTree, topScope);
+  ResolveNames(context_, parseTree, topScope);
   CHECK(modSymbol.has<ModuleDetails>());
   CHECK(modSymbol.test(Symbol::Flag::ModFile));
   if (isIntrinsic.value_or(false)) {

diff  --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index fc59a17fbbbea..95bbd10e2e7a3 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -355,6 +355,10 @@ void SemanticsContext::UseFortranBuiltinsModule() {
   }
 }
 
+parser::Program &SemanticsContext::SaveParseTree(parser::Program &&tree) {
+  return modFileParseTrees_.emplace_back(std::move(tree));
+}
+
 bool Semantics::Perform() {
   // Implicitly USE the __Fortran_builtins module so that special types
   // (e.g., __builtin_team_type) are available to semantics, esp. for


        


More information about the flang-commits mailing list