Skip to content

Commit f517e06

Browse files
authored
Merge pull request #59145 from CodaFi/devil-kissed-you-are
[5.7] Patch Out a Source of Iterator Invalidation
2 parents bddc511 + 613120e commit f517e06

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

include/swift/AST/FileUnit.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
5555
/// Returns the synthesized file for this source file, if it exists.
5656
SynthesizedFileUnit *getSynthesizedFile() const;
5757

58+
/// Returns the synthesized file for this source file, creating one and
59+
/// inserting it into the module if it does not exist.
60+
///
61+
/// \warning Because this function mutates the parent module's list of files,
62+
/// it will invalidate the iterators of any upstream callers of
63+
/// \c ModuleDecl::getFiles().
5864
SynthesizedFileUnit &getOrCreateSynthesizedFile();
5965

6066
/// Look up a (possibly overloaded) value set at top-level scope

lib/AST/Module.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,6 +3055,15 @@ SynthesizedFileUnit &FileUnit::getOrCreateSynthesizedFile() {
30553055
return *thisSynth;
30563056
SynthesizedFile = new (getASTContext()) SynthesizedFileUnit(*this);
30573057
SynthesizedFileAndKind.setPointer(SynthesizedFile);
3058+
// FIXME: Mutating the module in-flight is not a good idea. Any
3059+
// callers above us in the stack that are iterating over
3060+
// the module's files will have their iterators invalidated. There's
3061+
// a strong chance that whatever analysis led to this function being
3062+
// called is doing just that!
3063+
//
3064+
// Instead we ought to just call ModuleDecl::clearLookupCache() here
3065+
// and patch out the places looking for synthesized files hanging off of
3066+
// source files.
30583067
getParentModule()->addFile(*SynthesizedFile);
30593068
}
30603069
return *SynthesizedFile;

lib/Frontend/Frontend.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,8 +1166,13 @@ bool CompilerInstance::loadPartialModulesAndImplicitImports(
11661166
bool CompilerInstance::forEachFileToTypeCheck(
11671167
llvm::function_ref<bool(SourceFile &)> fn) {
11681168
if (isWholeModuleCompilation()) {
1169-
for (auto fileName : getMainModule()->getFiles()) {
1170-
auto *SF = dyn_cast<SourceFile>(fileName);
1169+
// FIXME: Do not refactor this to use an iterator as long as
1170+
// ModuleDecl::addFile is called during Sema. Synthesized files pushed
1171+
// during semantic analysis will cause iterator invalidation here.
1172+
// See notes in SourceFile::getOrCreateSynthesizedFile() for more.
1173+
unsigned i = 0;
1174+
while (i < getMainModule()->getFiles().size()) {
1175+
auto *SF = dyn_cast<SourceFile>(getMainModule()->getFiles()[i++]);
11711176
if (!SF) {
11721177
continue;
11731178
}

0 commit comments

Comments
 (0)