Skip to content

Commit 28fd20c

Browse files
committed
SIL: Fix assertion failure after deleting instructions that contain unresolved local archetypes
We maintained a counter of the number of pending local archetypes that had not yet been defined. However, if an instruction that references a pending local archetype was deleted before the local archetype was defined, the counter would never decrement. Before reading the counter value, garbage collect any inserted placeholders that have no uses. These correspond to pending local archetypes that are no longer in use and will never be defined.
1 parent 874afc3 commit 28fd20c

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

include/swift/SIL/SILModule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ class SILModule {
477477
/// This should only be the case during parsing or deserialization.
478478
bool hasUnresolvedLocalArchetypeDefinitions();
479479

480+
/// If we added any instructions that reference unresolved local archetypes
481+
/// and then deleted those instructions without resolving those archetypes,
482+
/// we must reclaim those unresolved local archetypes.
483+
void reclaimUnresolvedLocalArchetypeDefinitions();
484+
480485
/// Get a unique index for a struct or class field in layout order.
481486
///
482487
/// Precondition: \p decl must be a non-resilient struct or class.

lib/SIL/IR/SILModule.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,28 @@ SILValue SILModule::getRootLocalArchetypeDef(CanLocalArchetypeType archetype,
687687
return def;
688688
}
689689

690+
void SILModule::reclaimUnresolvedLocalArchetypeDefinitions() {
691+
llvm::DenseMap<LocalArchetypeKey, SILValue> newLocalArchetypeDefs;
692+
693+
for (auto pair : RootLocalArchetypeDefs) {
694+
if (auto *placeholder = dyn_cast<PlaceholderValue>(pair.second)) {
695+
// If a placeholder has no uses, the instruction that introduced it
696+
// was deleted before the local archetype was resolved. Reclaim the
697+
// placeholder so that we don't complain.
698+
if (placeholder->use_empty()) {
699+
assert(numUnresolvedLocalArchetypes > 0);
700+
--numUnresolvedLocalArchetypes;
701+
::delete placeholder;
702+
continue;
703+
}
704+
}
705+
706+
newLocalArchetypeDefs.insert(pair);
707+
}
708+
709+
std::swap(newLocalArchetypeDefs, RootLocalArchetypeDefs);
710+
}
711+
690712
bool SILModule::hasUnresolvedLocalArchetypeDefinitions() {
691713
return numUnresolvedLocalArchetypes != 0;
692714
}
@@ -753,6 +775,8 @@ void SILModule::notifyAddedInstruction(SILInstruction *inst) {
753775
auto *placeholder = cast<PlaceholderValue>(val);
754776
placeholder->replaceAllUsesWith(dependency);
755777
::delete placeholder;
778+
779+
assert(numUnresolvedLocalArchetypes > 0);
756780
numUnresolvedLocalArchetypes--;
757781
}
758782
val = dependency;

0 commit comments

Comments
 (0)