Skip to content

Commit 999669c

Browse files
authored
Merge pull request #78441 from stzn/improve-use-before-initialized-diagnostic
[Diagnostics] A self argument implicitly passed as an inout parameter is diagnosed as used before initialized
2 parents 78608b3 + d429a90 commit 999669c

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,8 +1734,13 @@ void LifetimeChecker::handleInOutUse(const DIMemoryUse &Use) {
17341734
return;
17351735
}
17361736

1737-
auto diagID = diag::variable_inout_before_initialized;
1738-
1737+
// A self argument implicitly passed as an inout parameter is diagnosed as
1738+
// "used before initialized", because "passed by reference" might be a
1739+
// confusing diagnostic in this context.
1740+
auto diagID = (Use.Kind == DIUseKind::InOutSelfArgument)
1741+
? diag::variable_used_before_initialized
1742+
: diag::variable_inout_before_initialized;
1743+
17391744
if (isa<AddressToPointerInst>(Use.Inst))
17401745
diagID = diag::variable_addrtaken_before_initialized;
17411746

test/SILOptimizer/definite_init_address_only_let.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,13 @@ func bas<T>(a: Bool, t: T) {
2929

3030
x = t
3131
}
32+
33+
func quz<T>(a: Bool, t: T) {
34+
let closure: (inout T) -> Void = { _ in }
35+
var x: T // expected-note {{defined here}}
36+
defer { closure(&x) } // expected-error{{variable 'x' passed by reference before being initialized}}
37+
if a {
38+
x = t
39+
return
40+
}
41+
}

test/SILOptimizer/definite_init_diagnostics.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,18 @@ func test2() {
125125
// expected-note@+1 {{'u2' declared here}}
126126
unowned let u2 = SomeClass()
127127
_ = u2 // ok
128+
129+
// Array
130+
var arr1: [String] // expected-note {{variable defined here}}
131+
arr1.append("item") // expected-error {{variable 'arr1' used before being initialized}}
132+
var arr2: [String] = []
133+
arr2.append("item") // ok
134+
135+
// Dictionary
136+
var d1: [String: Int] // expected-note {{variable defined here}}
137+
d1["key"] = 1 // expected-error {{variable 'd1' used before being initialized}}
138+
var d2: [String: Int] = [:]
139+
d2["key"] = 1 // ok
128140
}
129141

130142

@@ -1483,8 +1495,7 @@ func testOptionalChainingWithGenerics<T: DIOptionalTestProtocol>(p: T) -> T? {
14831495
// expected-note@-2 {{constant defined here}}
14841496

14851497
// note that here assignment to 'f' is a call to the setter.
1486-
x?.f = 0 // expected-error {{constant 'x' used before being initialized}}
1487-
// expected-error@-1 {{constant 'x' passed by reference before being initialized}}
1498+
x?.f = 0 // expected-error 2 {{constant 'x' used before being initialized}}
14881499
return x // expected-error {{constant 'x' used before being initialized}}
14891500
}
14901501

0 commit comments

Comments
 (0)