aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorBen Barham <ben_barham@apple.com>2021-07-15 18:24:09 -0700
committerVolodymyr Sapsai <vsapsai@apple.com>2021-07-15 18:27:08 -0700
commit766a08df12c111b15ed51d0fcac06042d2f68cd6 (patch)
tree5c1992bb428f9dfc537b6323dd4d122b681779ec /clang/lib/Frontend/CompilerInstance.cpp
parent3c4023b225ace3a5c0ed23bc491b47c9dad4353c (diff)
downloadllvm-766a08df12c111b15ed51d0fcac06042d2f68cd6.zip
llvm-766a08df12c111b15ed51d0fcac06042d2f68cd6.tar.gz
llvm-766a08df12c111b15ed51d0fcac06042d2f68cd6.tar.bz2
[Frontend] Only compile modules if not already finalized
It was possible to re-add a module to a shared in-memory module cache when search paths are changed. This can eventually cause a crash if the original module is referenced after this occurs. 1. Module A depends on B 2. B exists in two paths C and D 3. First run only has C on the search path, finds A and B and loads them 4. Second run adds D to the front of the search path. A is loaded and contains a reference to the already compiled module from C. But searching finds the module from D instead, causing a mismatch 5. B and the modules that depend on it are considered out of date and thus rebuilt 6. The recompiled module A is added to the in-memory cache, freeing the previously inserted one This can never occur from a regular clang process, but is very easy to do through the API - whether through the use of a shared case or just running multiple compilations from a single `CompilerInstance`. Update the compilation to return early if a module is already finalized so that the pre-condition in the in-memory module cache holds. Resolves rdar://78180255 Differential Revision: https://reviews.llvm.org/D105328
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index a6e2329..c642af1 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1054,6 +1054,15 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
[](CompilerInstance &) {}) {
llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
+ // Never compile a module that's already finalized - this would cause the
+ // existing module to be freed, causing crashes if it is later referenced
+ if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) {
+ ImportingInstance.getDiagnostics().Report(
+ ImportLoc, diag::err_module_rebuild_finalized)
+ << ModuleName;
+ return false;
+ }
+
// Construct a compiler invocation for creating this module.
auto Invocation =
std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());