Skip to content

Commit e441e72

Browse files
authored
Merge pull request swiftlang#23697 from compnerd/this-is-not-your-memory
Sema: avoid a use-after-free in `ResolvedMemberResult`
2 parents 9666123 + bebde5d commit e441e72

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

include/swift/Sema/IDETypeChecking.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,16 @@ namespace swift {
6565

6666
struct ResolvedMemberResult {
6767
struct Implementation;
68-
Implementation &Impl;
68+
Implementation *Impl;
6969

7070
ResolvedMemberResult();
7171
~ResolvedMemberResult();
72+
ResolvedMemberResult(const ResolvedMemberResult &) = delete;
73+
ResolvedMemberResult & operator=(ResolvedMemberResult &) = delete;
74+
ResolvedMemberResult(ResolvedMemberResult &&other) {
75+
Impl = other.Impl;
76+
other.Impl = nullptr;
77+
}
7278
operator bool() const;
7379
bool hasBestOverload() const;
7480
ValueDecl* getBestOverload() const;

lib/Sema/CSGen.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3773,28 +3773,28 @@ struct ResolvedMemberResult::Implementation {
37733773
Optional<unsigned> BestIdx;
37743774
};
37753775

3776-
ResolvedMemberResult::ResolvedMemberResult(): Impl(*new Implementation()) {};
3776+
ResolvedMemberResult::ResolvedMemberResult(): Impl(new Implementation()) {};
37773777

3778-
ResolvedMemberResult::~ResolvedMemberResult() { delete &Impl; };
3778+
ResolvedMemberResult::~ResolvedMemberResult() { delete Impl; };
37793779

37803780
ResolvedMemberResult::operator bool() const {
3781-
return !Impl.AllDecls.empty();
3781+
return !Impl->AllDecls.empty();
37823782
}
37833783

37843784
bool ResolvedMemberResult::
3785-
hasBestOverload() const { return Impl.BestIdx.hasValue(); }
3785+
hasBestOverload() const { return Impl->BestIdx.hasValue(); }
37863786

37873787
ValueDecl* ResolvedMemberResult::
3788-
getBestOverload() const { return Impl.AllDecls[Impl.BestIdx.getValue()]; }
3788+
getBestOverload() const { return Impl->AllDecls[Impl->BestIdx.getValue()]; }
37893789

37903790
ArrayRef<ValueDecl*> ResolvedMemberResult::
37913791
getMemberDecls(InterestedMemberKind Kind) {
3792-
auto Result = llvm::makeArrayRef(Impl.AllDecls);
3792+
auto Result = llvm::makeArrayRef(Impl->AllDecls);
37933793
switch (Kind) {
37943794
case InterestedMemberKind::Viable:
3795-
return Result.slice(Impl.ViableStartIdx);
3795+
return Result.slice(Impl->ViableStartIdx);
37963796
case InterestedMemberKind::Unviable:
3797-
return Result.slice(0, Impl.ViableStartIdx);
3797+
return Result.slice(0, Impl->ViableStartIdx);
37983798
case InterestedMemberKind::All:
37993799
return Result;
38003800
}
@@ -3816,10 +3816,10 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
38163816

38173817
// Keep track of all the unviable members.
38183818
for (auto Can : LookupResult.UnviableCandidates)
3819-
Result.Impl.AllDecls.push_back(Can.getDecl());
3819+
Result.Impl->AllDecls.push_back(Can.getDecl());
38203820

38213821
// Keep track of the start of viable choices.
3822-
Result.Impl.ViableStartIdx = Result.Impl.AllDecls.size();
3822+
Result.Impl->ViableStartIdx = Result.Impl->AllDecls.size();
38233823

38243824
// If no viable members, we are done.
38253825
if (LookupResult.ViableCandidates.empty())
@@ -3839,8 +3839,8 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
38393839

38403840
// If this VD is the best overload, keep track of its index.
38413841
if (VD == Selected)
3842-
Result.Impl.BestIdx = Result.Impl.AllDecls.size();
3843-
Result.Impl.AllDecls.push_back(VD);
3842+
Result.Impl->BestIdx = Result.Impl->AllDecls.size();
3843+
Result.Impl->AllDecls.push_back(VD);
38443844
}
38453845
return Result;
38463846
}
@@ -3898,4 +3898,4 @@ swift::getOriginalArgumentList(Expr *expr) {
38983898
}
38993899

39003900
return result;
3901-
}
3901+
}

0 commit comments

Comments
 (0)