mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Patch Out a Source of Iterator Invalidation
Synthesized file units were designed for autodiff to emit synthesized declarations, and also to sidestep the design implications of doing so late in the compiler pipeline. A call to materialize synthesized file units was added to the GetImplicitSendable request. This introduced a source of iterator invalidation into forEachFileToTypeCheck in whole-module builds. Any call to insert a new file into the module has the potential to cause the underlying SmallVector to reallocate. This patch provides a narrow workaround that stops using iterators altogether in forEachFileToTypeCheck. However, this bug reveals a severe architectural flaw in the concept of a synthesized file unit. Iterating over the files in a module is an extremely common operation, and there now are myriad ways we could wind up calling a function that mutates the module's list of files in the process. This also means the number and kind of files being visited by compiler analyses is dependent upon whether a request that inserts these files has or has not been called. This suggests the call to ModuleDecl::addFile in FileUnit::getOrCreateSynthesizedFile is deleterious and should be removed. Doing so will come as part of a larger refactoring. rdar://94043340
This commit is contained in:
@@ -3064,6 +3064,15 @@ SynthesizedFileUnit &FileUnit::getOrCreateSynthesizedFile() {
|
||||
return *thisSynth;
|
||||
SynthesizedFile = new (getASTContext()) SynthesizedFileUnit(*this);
|
||||
SynthesizedFileAndKind.setPointer(SynthesizedFile);
|
||||
// FIXME: Mutating the module in-flight is not a good idea. Any
|
||||
// callers above us in the stack that are iterating over
|
||||
// the module's files will have their iterators invalidated. There's
|
||||
// a strong chance that whatever analysis led to this function being
|
||||
// called is doing just that!
|
||||
//
|
||||
// Instead we ought to just call ModuleDecl::clearLookupCache() here
|
||||
// and patch out the places looking for synthesized files hanging off of
|
||||
// source files.
|
||||
getParentModule()->addFile(*SynthesizedFile);
|
||||
}
|
||||
return *SynthesizedFile;
|
||||
|
||||
Reference in New Issue
Block a user