Skip to content

Commit 8d2c85d

Browse files
authored
Merge pull request #34357 from gottesmm/pr-5b70b29de84d902644bc21dc530816c78e919469
[silgen] Ensure that cleanup cloner clones formal access cleanups to formal access cleanups.
2 parents 09fc82a + f0a59a2 commit 8d2c85d

File tree

3 files changed

+31
-10
lines changed

3 files changed

+31
-10
lines changed

lib/SILGen/Cleanup.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,16 @@ void CleanupStateRestorationScope::pop() && { popImpl(); }
359359
//===----------------------------------------------------------------------===//
360360

361361
CleanupCloner::CleanupCloner(SILGenFunction &SGF, const ManagedValue &mv)
362-
: SGF(SGF), hasCleanup(mv.hasCleanup()), isLValue(mv.isLValue()),
363-
writebackBuffer(None) {
362+
: SGF(SGF), writebackBuffer(None), hasCleanup(mv.hasCleanup()),
363+
isLValue(mv.isLValue()), isFormalAccess(false) {
364364
if (hasCleanup) {
365365
auto handle = mv.getCleanup();
366366
auto state = SGF.Cleanups.getFlagsAndWritebackBuffer(handle);
367-
if (SILValue value = std::get<1>(state).getValueOr(SILValue())) {
367+
using RawTy = std::underlying_type<Cleanup::Flags>::type;
368+
if (RawTy(std::get<0>(state)) & RawTy(Cleanup::Flags::FormalAccessCleanup))
369+
isFormalAccess = true;
370+
if (SILValue value = std::get<1>(state).getValueOr(SILValue()))
368371
writebackBuffer = value;
369-
}
370372
}
371373
}
372374

@@ -405,8 +407,16 @@ ManagedValue CleanupCloner::clone(SILValue value) const {
405407
}
406408

407409
if (value->getType().isAddress()) {
410+
if (isFormalAccess) {
411+
auto loc = RegularLocation::getAutoGeneratedLocation();
412+
return SGF.emitFormalAccessManagedBufferWithCleanup(loc, value);
413+
}
408414
return SGF.emitManagedBufferWithCleanup(value);
409415
}
410416

417+
if (isFormalAccess) {
418+
auto loc = RegularLocation::getAutoGeneratedLocation();
419+
return SGF.emitFormalAccessManagedRValueWithCleanup(loc, value);
420+
}
411421
return SGF.emitManagedRValueWithCleanup(value);
412422
}

lib/SILGen/Cleanup.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ class LLVM_LIBRARY_VISIBILITY Cleanup {
8484
//
8585
// Example: Distinguishing in between @owned cleanups with a writeback buffer
8686
// (ExclusiveBorrowCleanup) or ones that involve formal access cleanups.
87-
enum class Flags : uint8_t {
87+
enum Flags : uint8_t {
8888
None = 0,
89-
ExclusiveBorrowCleanup = 1,
89+
FormalAccessCleanup = 1,
9090
};
9191

9292
private:
@@ -95,7 +95,7 @@ class LLVM_LIBRARY_VISIBILITY Cleanup {
9595
Flags flags : 8;
9696

9797
protected:
98-
Cleanup() {}
98+
Cleanup() : flags(Flags::None) {}
9999
virtual ~Cleanup() {}
100100

101101
public:
@@ -123,6 +123,14 @@ class LLVM_LIBRARY_VISIBILITY Cleanup {
123123
virtual bool getWritebackBuffer(function_ref<void(SILValue)> func) {
124124
return false;
125125
}
126+
127+
bool isFormalAccess() const {
128+
return getFlags() & Flags::FormalAccessCleanup;
129+
}
130+
131+
void setIsFormalAccess() {
132+
flags = Flags(flags | Flags::FormalAccessCleanup);
133+
}
126134
};
127135

128136
/// A cleanup depth is generally used to denote the set of cleanups
@@ -310,9 +318,10 @@ class CleanupStateRestorationScope {
310318
/// writeback buffers.
311319
class CleanupCloner {
312320
SILGenFunction &SGF;
321+
Optional<SILValue> writebackBuffer;
313322
bool hasCleanup;
314323
bool isLValue;
315-
Optional<SILValue> writebackBuffer;
324+
bool isFormalAccess;
316325

317326
public:
318327
CleanupCloner(SILGenFunction &SGF, const ManagedValue &mv);

lib/SILGen/SILGenDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,10 +1431,12 @@ SILGenFunction::enterDormantTemporaryCleanup(SILValue addr,
14311431

14321432
namespace {
14331433

1434-
struct FormalAccessReleaseValueCleanup : Cleanup {
1434+
struct FormalAccessReleaseValueCleanup final : Cleanup {
14351435
FormalEvaluationContext::stable_iterator Depth;
14361436

1437-
FormalAccessReleaseValueCleanup() : Depth() {}
1437+
FormalAccessReleaseValueCleanup() : Cleanup(), Depth() {
1438+
setIsFormalAccess();
1439+
}
14381440

14391441
void setState(SILGenFunction &SGF, CleanupState newState) override {
14401442
if (newState == CleanupState::Dead) {

0 commit comments

Comments
 (0)