summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2019-11-03 19:29:29 -0800
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2019-11-03 19:57:33 -0800
commit31e14f41a21f9016050a20f07d5da03db2e8c13e (patch)
tree414a5b696961e951b4170658023c6d674756b71b /clang/lib/Frontend/CompilerInstance.cpp
parent858b15cb9cf675b33d5c3bf17b3050d98b73ec3f (diff)
downloadbcm5719-llvm-31e14f41a21f9016050a20f07d5da03db2e8c13e.tar.gz
bcm5719-llvm-31e14f41a21f9016050a20f07d5da03db2e8c13e.zip
clang/Modules: Sink CompilerInstance::KnownModules into ModuleMap
Avoid use-after-frees when FrontendAction::BeginSourceFile is called twice on the same CompilerInstance by sinking CompilerInstance::KnownModules into ModuleMap. On the way, rename the map to CachedModuleLoads. I considered (but rejected) merging this with ModuleMap::Modules, since that only has top-level modules and this map includes submodules. This is an alternative to https://reviews.llvm.org/D58497. Thanks to nemanjai for the detailed analysis of the problem!
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp34
1 files changed, 14 insertions, 20 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index c409c07ff13..cc3d848c1e0 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1541,12 +1541,9 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
}
void registerAll() {
- for (auto *II : LoadedModules) {
- CI.KnownModules[II] = CI.getPreprocessor()
- .getHeaderSearchInfo()
- .getModuleMap()
- .findModule(II->getName());
- }
+ ModuleMap &MM = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap();
+ for (auto *II : LoadedModules)
+ MM.cacheModuleLoad(*II, MM.findModule(II->getName()));
LoadedModules.clear();
}
@@ -1635,14 +1632,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
return LastModuleImportResult;
}
- clang::Module *Module = nullptr;
-
// If we don't already have information on this module, load the module now.
- llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
- = KnownModules.find(Path[0].first);
- if (Known != KnownModules.end()) {
- // Retrieve the cached top-level module.
- Module = Known->second;
+ ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
+ clang::Module *Module = MM.getCachedModuleLoad(*Path[0].first);
+ if (Module) {
+ // Nothing to do here, we found it.
} else if (ModuleName == getLangOpts().CurrentModule) {
// This is the module we're building.
Module = PP->getHeaderSearchInfo().lookupModule(
@@ -1656,7 +1650,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// ModuleBuildFailed = true;
// return ModuleLoadResult();
//}
- Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
+ MM.cacheModuleLoad(*Path[0].first, Module);
} else {
// Search for a module with the given name.
Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true,
@@ -1750,7 +1744,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt)
<< ModuleName;
ModuleBuildFailed = true;
- KnownModules[Path[0].first] = nullptr;
+ MM.cacheModuleLoad(*Path[0].first, nullptr);
return ModuleLoadResult();
}
}
@@ -1764,7 +1758,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// necessarily even have a module map. Since ReadAST already produces
// diagnostics for these two cases, we simply error out here.
ModuleBuildFailed = true;
- KnownModules[Path[0].first] = nullptr;
+ MM.cacheModuleLoad(*Path[0].first, nullptr);
return ModuleLoadResult();
}
@@ -1809,7 +1803,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
"undiagnosed error in compileAndLoadModule");
if (getPreprocessorOpts().FailedModules)
getPreprocessorOpts().FailedModules->addFailed(ModuleName);
- KnownModules[Path[0].first] = nullptr;
+ MM.cacheModuleLoad(*Path[0].first, nullptr);
ModuleBuildFailed = true;
return ModuleLoadResult();
}
@@ -1832,19 +1826,19 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
ModuleLoader::HadFatalFailure = true;
// FIXME: The ASTReader will already have complained, but can we shoehorn
// that diagnostic information into a more useful form?
- KnownModules[Path[0].first] = nullptr;
+ MM.cacheModuleLoad(*Path[0].first, nullptr);
return ModuleLoadResult();
case ASTReader::Failure:
ModuleLoader::HadFatalFailure = true;
// Already complained, but note now that we failed.
- KnownModules[Path[0].first] = nullptr;
+ MM.cacheModuleLoad(*Path[0].first, nullptr);
ModuleBuildFailed = true;
return ModuleLoadResult();
}
// Cache the result of this top-level module lookup for later.
- Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
+ MM.cacheModuleLoad(*Path[0].first, Module);
}
// If we never found the module, fail.
OpenPOWER on IntegriCloud