Skip to content

Commit 08b2e65

Browse files
authored
Merge pull request #155 from dexonsmith/clang/cherry-pick-known-modules-use-after-free-fix-for-20190619
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. This includes two cherry-picks: - 63c140d - ca98e30
2 parents 2455aca + ca98e30 commit 08b2e65

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,6 @@ class CompilerInstance : public ModuleLoader {
126126

127127
std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
128128

129-
/// The set of top-level modules that has already been loaded,
130-
/// along with the module map
131-
llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
132-
133129
/// The set of top-level modules that has already been built on the
134130
/// fly as part of this overall compilation action.
135131
std::map<std::string, std::string> BuiltModules;

clang/include/clang/Lex/ModuleMap.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@
1414
#ifndef LLVM_CLANG_LEX_MODULEMAP_H
1515
#define LLVM_CLANG_LEX_MODULEMAP_H
1616

17+
#include "clang/Basic/IdentifierTable.h"
1718
#include "clang/Basic/LangOptions.h"
1819
#include "clang/Basic/Module.h"
1920
#include "clang/Basic/SourceLocation.h"
2021
#include "llvm/ADT/ArrayRef.h"
2122
#include "llvm/ADT/DenseMap.h"
2223
#include "llvm/ADT/PointerIntPair.h"
23-
#include "llvm/ADT/StringSet.h"
2424
#include "llvm/ADT/SmallPtrSet.h"
2525
#include "llvm/ADT/SmallVector.h"
2626
#include "llvm/ADT/StringMap.h"
2727
#include "llvm/ADT/StringRef.h"
28+
#include "llvm/ADT/StringSet.h"
2829
#include "llvm/ADT/TinyPtrVector.h"
2930
#include "llvm/ADT/Twine.h"
3031
#include <ctime>
@@ -108,6 +109,10 @@ class ModuleMap {
108109
/// The top-level modules that are known.
109110
llvm::StringMap<Module *> Modules;
110111

112+
/// Module loading cache that includes submodules, indexed by IdentifierInfo.
113+
/// nullptr is stored for modules that are known to fail to load.
114+
llvm::DenseMap<const IdentifierInfo *, Module *> CachedModuleLoads;
115+
111116
/// Shadow modules created while building this module map.
112117
llvm::SmallVector<Module*, 2> ShadowModules;
113118

@@ -695,6 +700,19 @@ class ModuleMap {
695700

696701
module_iterator module_begin() const { return Modules.begin(); }
697702
module_iterator module_end() const { return Modules.end(); }
703+
704+
/// Cache a module load. M might be nullptr.
705+
void cacheModuleLoad(const IdentifierInfo &II, Module *M) {
706+
CachedModuleLoads[&II] = M;
707+
}
708+
709+
/// Return a cached module load.
710+
llvm::Optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) {
711+
auto I = CachedModuleLoads.find(&II);
712+
if (I == CachedModuleLoads.end())
713+
return None;
714+
return I->second;
715+
}
698716
};
699717

700718
} // namespace clang

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,12 +1560,9 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
15601560
}
15611561

15621562
void registerAll() {
1563-
for (auto *II : LoadedModules) {
1564-
CI.KnownModules[II] = CI.getPreprocessor()
1565-
.getHeaderSearchInfo()
1566-
.getModuleMap()
1567-
.findModule(II->getName());
1568-
}
1563+
ModuleMap &MM = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap();
1564+
for (auto *II : LoadedModules)
1565+
MM.cacheModuleLoad(*II, MM.findModule(II->getName()));
15691566
LoadedModules.clear();
15701567
}
15711568

@@ -1654,14 +1651,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
16541651
return LastModuleImportResult;
16551652
}
16561653

1657-
clang::Module *Module = nullptr;
1658-
16591654
// If we don't already have information on this module, load the module now.
1660-
llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
1661-
= KnownModules.find(Path[0].first);
1662-
if (Known != KnownModules.end()) {
1663-
// Retrieve the cached top-level module.
1664-
Module = Known->second;
1655+
Module *Module = nullptr;
1656+
ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
1657+
if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
1658+
// Use the cached result, which may be nullptr.
1659+
Module = *MaybeModule;
16651660
} else if (ModuleName == getLangOpts().CurrentModule) {
16661661
// This is the module we're building.
16671662
Module = PP->getHeaderSearchInfo().lookupModule(
@@ -1675,7 +1670,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
16751670
// ModuleBuildFailed = true;
16761671
// return ModuleLoadResult();
16771672
//}
1678-
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1673+
MM.cacheModuleLoad(*Path[0].first, Module);
16791674
} else {
16801675
// Search for a module with the given name.
16811676
Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true,
@@ -1769,7 +1764,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
17691764
getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt)
17701765
<< ModuleName;
17711766
ModuleBuildFailed = true;
1772-
KnownModules[Path[0].first] = nullptr;
1767+
MM.cacheModuleLoad(*Path[0].first, nullptr);
17731768
return ModuleLoadResult();
17741769
}
17751770
}
@@ -1783,7 +1778,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
17831778
// necessarily even have a module map. Since ReadAST already produces
17841779
// diagnostics for these two cases, we simply error out here.
17851780
ModuleBuildFailed = true;
1786-
KnownModules[Path[0].first] = nullptr;
1781+
MM.cacheModuleLoad(*Path[0].first, nullptr);
17871782
return ModuleLoadResult();
17881783
}
17891784

@@ -1828,7 +1823,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
18281823
"undiagnosed error in compileAndLoadModule");
18291824
if (getPreprocessorOpts().FailedModules)
18301825
getPreprocessorOpts().FailedModules->addFailed(ModuleName);
1831-
KnownModules[Path[0].first] = nullptr;
1826+
MM.cacheModuleLoad(*Path[0].first, nullptr);
18321827
ModuleBuildFailed = true;
18331828
return ModuleLoadResult();
18341829
}
@@ -1851,19 +1846,19 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
18511846
ModuleLoader::HadFatalFailure = true;
18521847
// FIXME: The ASTReader will already have complained, but can we shoehorn
18531848
// that diagnostic information into a more useful form?
1854-
KnownModules[Path[0].first] = nullptr;
1849+
MM.cacheModuleLoad(*Path[0].first, nullptr);
18551850
return ModuleLoadResult();
18561851

18571852
case ASTReader::Failure:
18581853
ModuleLoader::HadFatalFailure = true;
18591854
// Already complained, but note now that we failed.
1860-
KnownModules[Path[0].first] = nullptr;
1855+
MM.cacheModuleLoad(*Path[0].first, nullptr);
18611856
ModuleBuildFailed = true;
18621857
return ModuleLoadResult();
18631858
}
18641859

18651860
// Cache the result of this top-level module lookup for later.
1866-
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1861+
MM.cacheModuleLoad(*Path[0].first, Module);
18671862
}
18681863

18691864
// If we never found the module, fail.

0 commit comments

Comments
 (0)