Skip to content

Commit 5798e71

Browse files
committed
[MemoryLifetimeVerifier] Permit leaks in dead-ends
1 parent 8e98bcf commit 5798e71

File tree

5 files changed

+31
-46
lines changed

5 files changed

+31
-46
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,8 @@ class SILFunction
16761676
}
16771677

16781678
/// Verifies the lifetime of memory locations in the function.
1679-
void verifyMemoryLifetime(CalleeCache *calleeCache);
1679+
void verifyMemoryLifetime(CalleeCache *calleeCache,
1680+
DeadEndBlocks *deadEndBlocks);
16801681

16811682
/// Verifies ownership of the function.
16821683
/// Since we don't have complete lifetimes everywhere, computes DeadEndBlocks

lib/SIL/Verifier/MemoryLifetimeVerifier.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212

1313
#define DEBUG_TYPE "sil-memory-lifetime-verifier"
1414
#include "swift/Basic/Assertions.h"
15-
#include "swift/SIL/MemoryLocations.h"
15+
#include "swift/SIL/ApplySite.h"
16+
#include "swift/SIL/BasicBlockDatastructures.h"
17+
#include "swift/SIL/BasicBlockUtils.h"
1618
#include "swift/SIL/BitDataflow.h"
1719
#include "swift/SIL/CalleeCache.h"
20+
#include "swift/SIL/MemoryLocations.h"
1821
#include "swift/SIL/SILBasicBlock.h"
1922
#include "swift/SIL/SILFunction.h"
20-
#include "swift/SIL/ApplySite.h"
21-
#include "swift/SIL/BasicBlockDatastructures.h"
2223
#include "llvm/Support/CommandLine.h"
2324

2425
using namespace swift;
@@ -43,6 +44,7 @@ class MemoryLifetimeVerifier {
4344

4445
SILFunction *function;
4546
CalleeCache *calleeCache;
47+
DeadEndBlocks *deadEndBlocks;
4648
MemoryLocations locations;
4749

4850
/// alloc_stack memory locations which are used for store_borrow.
@@ -140,11 +142,12 @@ class MemoryLifetimeVerifier {
140142
}
141143

142144
public:
143-
MemoryLifetimeVerifier(SILFunction *function, CalleeCache *calleeCache) :
144-
function(function),
145-
calleeCache(calleeCache),
146-
locations(/*handleNonTrivialProjections*/ true,
147-
/*handleTrivialLocations*/ true) {}
145+
MemoryLifetimeVerifier(SILFunction *function, CalleeCache *calleeCache,
146+
DeadEndBlocks *deadEndBlocks)
147+
: function(function), calleeCache(calleeCache),
148+
deadEndBlocks(deadEndBlocks),
149+
locations(/*handleNonTrivialProjections*/ true,
150+
/*handleTrivialLocations*/ true) {}
148151

149152
/// The main entry point to verify the lifetime of all memory locations in
150153
/// the function.
@@ -883,7 +886,12 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
883886
}
884887
case SILInstructionKind::DeallocStackInst: {
885888
SILValue opVal = cast<DeallocStackInst>(&I)->getOperand();
886-
requireBitsClear(bits & nonTrivialLocations, opVal, &I);
889+
if (!deadEndBlocks->isDeadEnd(I.getParent())) {
890+
// TODO: rdar://159311784: Maybe at some point the invariant will be
891+
// enforced that values stored into addresses
892+
// don't leak in dead-ends.
893+
requireBitsClear(bits & nonTrivialLocations, opVal, &I);
894+
}
887895
// Needed to clear any bits of trivial locations (which are not required
888896
// to be zero).
889897
locations.clearBits(bits, opVal);
@@ -973,7 +981,8 @@ void MemoryLifetimeVerifier::verify() {
973981

974982
} // anonymous namespace
975983

976-
void SILFunction::verifyMemoryLifetime(CalleeCache *calleeCache) {
977-
MemoryLifetimeVerifier verifier(this, calleeCache);
984+
void SILFunction::verifyMemoryLifetime(CalleeCache *calleeCache,
985+
DeadEndBlocks *deadEndBlocks) {
986+
MemoryLifetimeVerifier verifier(this, calleeCache, deadEndBlocks);
978987
verifier.verify();
979988
}

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7380,7 +7380,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
73807380

73817381
if (F->hasOwnership() && F->shouldVerifyOwnership() &&
73827382
!mod.getASTContext().hadError()) {
7383-
F->verifyMemoryLifetime(calleeCache);
7383+
F->verifyMemoryLifetime(calleeCache, &getDeadEndBlocks());
73847384
}
73857385
}
73867386

test/SIL/memory_lifetime.sil

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,11 @@ bb0:
864864
%10 = tuple ()
865865
return %10
866866
}
867+
868+
sil [ossa] @storage_leaked_into_dead_ends : $@convention(thin) () -> () {
869+
%t = apply undef() : $@convention(thin) () -> (@owned T)
870+
%t_addr = alloc_stack $T
871+
store %t to [init] %t_addr
872+
dealloc_stack %t_addr
873+
unreachable
874+
}

test/SILOptimizer/allocbox_to_stack_ownership.sil

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,39 +1205,6 @@ bb0(%0 : $*T, %1 : $*T, %2 : $*T):
12051205
return %15 : $()
12061206
}
12071207

1208-
// CHECK-LABEL: sil [ossa] @alloc_box_in_specialized_callee :
1209-
// CHECK-NOT: alloc_box
1210-
// CHECK-LABEL: } // end sil function 'alloc_box_in_specialized_callee'
1211-
sil [ossa] @alloc_box_in_specialized_callee : $@convention(thin) (Int) -> () {
1212-
bb0(%0 : $Int):
1213-
%1 = alloc_box ${ var Int }
1214-
%2 = project_box %1, 0
1215-
store %0 to [trivial] %2
1216-
%4 = function_ref @callee_with_allocbox : $@convention(thin) (@guaranteed { var Int }) -> ()
1217-
%5 = apply %4(%1) : $@convention(thin) (@guaranteed { var Int }) -> ()
1218-
destroy_value %1
1219-
%r = tuple ()
1220-
return %r
1221-
}
1222-
1223-
// CHECK-LABEL: sil shared [ossa] @$s20callee_with_allocboxTf0s_n :
1224-
// CHECK-NOT: alloc_box
1225-
// CHECK-LABEL: } // end sil function '$s20callee_with_allocboxTf0s_n'
1226-
1227-
// CHECK-LABEL: sil [ossa] @callee_with_allocbox :
1228-
// CHECK-NOT: alloc_box
1229-
// CHECK-LABEL: } // end sil function 'callee_with_allocbox'
1230-
sil [ossa] @callee_with_allocbox : $@convention(thin) (@guaranteed { var Int }) -> () {
1231-
bb0(%0 : @guaranteed ${ var Int }):
1232-
%1 = alloc_box ${ var Int }
1233-
%2 = project_box %1 : ${ var Int }, 0
1234-
%3 = project_box %0 : ${ var Int }, 0
1235-
copy_addr %3 to %2
1236-
destroy_value %1
1237-
%r = tuple ()
1238-
return %r
1239-
}
1240-
12411208
sil @getC : $@convention(thin) () -> (@owned C)
12421209

12431210
// CHECK-LABEL: sil [ossa] @leak_to_inf_loop_1 : {{.*}} {

0 commit comments

Comments
 (0)