[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
This commit is contained in:
Peter Klausler 2022-04-25 16:00:01 -07:00
parent 6753bb2c41
commit f4bb211a3b
3 changed files with 14 additions and 4 deletions

View File

@ -195,6 +195,10 @@ public:
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 @@ private:
UnorderedSymbolSet errorSymbols_;
std::set<std::string> tempNames_;
const Scope *builtinsScope_{nullptr}; // module __Fortran_builtins
std::list<parser::Program> modFileParseTrees_;
};
class Semantics {

View File

@ -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)) {

View File

@ -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