Skip to content

Commit 8e50528

Browse files
committed
[Constraint solver] De-duplicate potential throw sites when merging partial solutions
Failure to deduplicate potential throw sites could cause these data structures to grow expotentially. De-duplicate in the obvious way, noting that we still need an effective data structure here.
1 parent 268d36d commit 8e50528

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,15 @@ struct PotentialThrowSite {
14661466

14671467
/// The locator that specifies where the throwing operation occurs.
14681468
ConstraintLocator *locator;
1469+
1470+
friend bool operator==(const PotentialThrowSite& lhs, const PotentialThrowSite &rhs) {
1471+
return lhs.kind == rhs.kind && lhs.type.getPointer() == rhs.type.getPointer() &&
1472+
lhs.locator == rhs.locator;
1473+
}
1474+
1475+
friend bool operator!=(const PotentialThrowSite& lhs, const PotentialThrowSite &rhs) {
1476+
return !(lhs == rhs);
1477+
}
14691478
};
14701479

14711480
/// A complete solution to a constraint system.

lib/Sema/CSSolver.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,21 @@ void ConstraintSystem::applySolution(const Solution &solution) {
353353
setCaseLabelItemInfo(info.first, info.second);
354354
}
355355

356-
potentialThrowSites.insert(potentialThrowSites.end(),
357-
solution.potentialThrowSites.begin(),
358-
solution.potentialThrowSites.end());
356+
if (!potentialThrowSites.empty() && !solution.potentialThrowSites.empty()) {
357+
DenseMap<void *, std::vector<PotentialThrowSite>> known;
358+
for (const auto &throwSite : potentialThrowSites) {
359+
known[throwSite.first.getOpaqueValue()].push_back(throwSite.second);
360+
}
361+
362+
for (const auto &throwSite : solution.potentialThrowSites) {
363+
auto &sites = known[throwSite.first.getOpaqueValue()];
364+
if (std::find(sites.begin(), sites.end(), throwSite.second) != sites.end())
365+
continue;
366+
367+
sites.push_back(throwSite.second);
368+
potentialThrowSites.push_back(throwSite);
369+
}
370+
}
359371

360372
for (auto param : solution.isolatedParams) {
361373
isolatedParams.insert(param);

0 commit comments

Comments
 (0)