mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The handling of multi-basic-block control flow in `defer` blocks looks like it was left incomplete and completely untested; I fixed a few obvious problems but it still completely lacks any analysis of conditional reinitializations. For now, change it to treat attempted reinitializations as uses-after-consumes so we raise reliable errors now instead of emitting code that causes memory corruption at runtime. Fixes rdar://129303198.
53 lines
1.5 KiB
Swift
53 lines
1.5 KiB
Swift
// RUN: %target-swift-frontend -emit-sil -verify %s
|
|
|
|
func consume<T>(_: consuming T) {}
|
|
|
|
func testSingleBlock<T>(x: inout T, y: T) {
|
|
defer { x = y }
|
|
consume(consume x)
|
|
}
|
|
|
|
func cond() -> Bool { fatalError() }
|
|
|
|
// TODO: should be accepted
|
|
func testAlwaysReinitAfterConditional<T>(x: inout T, y: T) { // not-really expected-error{{used after consume}}
|
|
defer {
|
|
if cond() { }
|
|
x = y // not-really expected-note{{}}
|
|
}
|
|
consume(consume x) // not-really expected-note{{}}
|
|
}
|
|
|
|
// TODO: should be accepted
|
|
func testAlwaysReinitBeforeConditional<T>(x: inout T, y: T) { // not-really expected-error{{used after consume}}
|
|
defer {
|
|
x = y // not-really expected-note{{}}
|
|
if cond() { }
|
|
}
|
|
consume(consume x) // not-really expected-note{{}}
|
|
}
|
|
|
|
// TODO: should be accepted
|
|
func testAlwaysReinitInBothBranchesOfConditional<T>(x: inout T, y: T) { // not-really expected-error{{used after consume}}
|
|
defer {
|
|
if cond() {
|
|
x = y // not-really expected-note{{}}
|
|
} else {
|
|
x = y
|
|
}
|
|
}
|
|
consume(consume x) // not-really expected-note{{}}
|
|
}
|
|
|
|
// TODO: should raise an error about inout not being reinitialized on all paths
|
|
func testSometimesReinitInConditional<T>(x: inout T, y: T) { // not-really expected-error{{used after consume}}
|
|
defer {
|
|
if cond() {
|
|
x = y // not-really expected-note{{}}
|
|
} else {
|
|
// ex/pected-note {{not initialized on this path}}
|
|
}
|
|
}
|
|
consume(consume x) // not-really expected-note{{}}
|
|
}
|