forked from OSchip/llvm-project
[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:
parent
6753bb2c41
commit
f4bb211a3b
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue