Skip to content

Commit 1998214

Browse files
committed
MoveOnlyAddressChecker: Turn assertion into early exit.
This condition can occur in practice if, while doing the walk back to find the liveness reason for a consume-without-reinitialization of an `inout` binding through conditional control flow, we visit a block that reinitializes the binding before any branch that leaves the binding uninitialized. Fixes rdar://123604613.
1 parent 372de46 commit 1998214

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,13 +2933,13 @@ bool GlobalLivenessChecker::testInstVectorLiveness(
29332933
continue;
29342934
case IsLive::LiveOut: {
29352935
LLVM_DEBUG(llvm::dbgs() << " Live out block!\n");
2936-
// If we see a live out block that is also a def block, we need to fa
2937-
#ifndef NDEBUG
2936+
// If we see a live out block that is also a def block, skip.
29382937
SmallBitVector defBits(addressUseState.getNumSubelements());
29392938
liveness.isDefBlock(block, errorSpan, defBits);
2940-
assert((defBits & errorSpan).none() &&
2941-
"If in def block... we are in liveness block");
2942-
#endif
2939+
if (!(defBits & errorSpan).none()) {
2940+
LLVM_DEBUG(llvm::dbgs() << " Also a def block; skipping!\n");
2941+
continue;
2942+
}
29432943
[[clang::fallthrough]];
29442944
}
29452945
case IsLive::LiveWithin:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//RUN: %target-swift-frontend -emit-sil -verify %s
2+
3+
@_silgen_name("cond")
4+
func cond() -> Bool
5+
6+
struct Foo: ~Copyable {}
7+
8+
func consume(_: consuming Foo) {}
9+
10+
func test1(_ x: inout Foo, _ y: consuming Foo) { // expected-error{{missing reinitialization}}
11+
consume(x) // expected-note{{consumed here}}
12+
if cond() {
13+
return
14+
} else {
15+
x = y
16+
}
17+
}
18+
19+
func test2(_ x: inout Foo, _ y: consuming Foo) { // expected-error{{missing reinitialization}}
20+
consume(x) // expected-note{{consumed here}}
21+
if cond() {
22+
x = y
23+
} else {
24+
return
25+
}
26+
}

0 commit comments

Comments
 (0)