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.
- Module A depends on B
- B exists in two paths C and D
- First run only has C on the search path, finds A and B and loads them
- 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
- B and the modules that depend on it are considered out of date and thus rebuilt
- 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
Can we get in infinite loop with AllowPCMWithCompilerErrors = true? Specifically, I'm thinking about the scenario
Haven't tried to reproduce it locally but even if this scenario is impossible, a corresponding test case can be useful.