Skip to content

Commit 619ce79

Browse files
authored
Merge pull request #59144 from CodaFi/sunkissed-you-are-not
Patch Out a Source of Iterator Invalidation
2 parents 1cb1546 + bbe4608 commit 619ce79

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
@@ -3064,6 +3064,15 @@ SynthesizedFileUnit &FileUnit::getOrCreateSynthesizedFile() {
30643064
return *thisSynth;
30653065
SynthesizedFile = new (getASTContext()) SynthesizedFileUnit(*this);
30663066
SynthesizedFileAndKind.setPointer(SynthesizedFile);
3067+
// FIXME: Mutating the module in-flight is not a good idea. Any
3068+
// callers above us in the stack that are iterating over
3069+
// the module's files will have their iterators invalidated. There's
3070+
// a strong chance that whatever analysis led to this function being
3071+
// called is doing just that!
3072+
//
3073+
// Instead we ought to just call ModuleDecl::clearLookupCache() here
3074+
// and patch out the places looking for synthesized files hanging off of
3075+
// source files.
30673076
getParentModule()->addFile(*SynthesizedFile);
30683077
}
30693078
return *SynthesizedFile;

lib/Frontend/Frontend.cpp

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

0 commit comments

Comments
 (0)