Skip to content

Commit 381f397

Browse files
committed
[Runtime] Fix swift_weakTakeStrong().
It turns out that when taking the last weak reference for an object that has been deallocated, we might have returned a non-null pointer when we shouldn't have. Which is exciting. rdar://106375185
1 parent 727bccd commit 381f397

File tree

2 files changed

+4
-4
lines changed

2 files changed

+4
-4
lines changed

stdlib/public/SwiftShims/swift/shims/RefCount.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,17 +1457,18 @@ class HeapObjectSideTableEntry {
14571457
return this;
14581458
}
14591459

1460-
void decrementWeak() {
1460+
bool decrementWeak() {
14611461
// FIXME: assertions
14621462
// FIXME: optimize barriers
14631463
bool cleanup = refCounts.decrementWeakShouldCleanUp();
14641464
if (!cleanup)
1465-
return;
1465+
return false;
14661466

14671467
// Weak ref count is now zero. Delete the side table entry.
14681468
// FREED -> DEAD
14691469
assert(refCounts.getUnownedCount() == 0);
14701470
swift_cxx_deleteObject(this);
1471+
return true;
14711472
}
14721473

14731474
void decrementWeakNonAtomic() {

stdlib/public/runtime/WeakReference.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,7 @@ class WeakReference {
174174

175175
HeapObject *nativeTakeStrongFromBits(WeakReferenceBits bits) {
176176
auto side = bits.getNativeOrNull();
177-
if (side) {
178-
side->decrementWeak();
177+
if (side && !side->decrementWeak()) {
179178
return side->tryRetain();
180179
} else {
181180
return nullptr;

0 commit comments

Comments
 (0)