Skip to content

Commit 9211c7c

Browse files
committed
Better diagnose error coming from unwrapping optional before initialized.
Added a check for whether the escape use is due to an UncheckedTakeEnumDataAddrInst, which accesses the memory to grab the .Some part of an Optional during “?.” or “!”. In that case, use the generic used-before-initialized diagnostic, since it isn’t actually because of closure capture. Added test cases, including specifically testing that capturing in a closure in order to unwrap the optional is still ok.
1 parent d47cded commit 9211c7c

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

lib/SILPasses/EarlySIL/DefiniteInitialization.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,8 @@ void LifetimeChecker::handleEscapeUse(const DIMemoryUse &Use) {
10941094
DiagMessage = diag::variable_closure_use_uninit;
10951095
else
10961096
DiagMessage = diag::variable_function_use_uninit;
1097+
} else if (isa<UncheckedTakeEnumDataAddrInst>(Inst)) {
1098+
DiagMessage = diag::variable_used_before_initialized;
10971099
} else {
10981100
DiagMessage = diag::variable_closure_use_uninit;
10991101
}

test/SILPasses/definite_init_diagnostics.swift

+12
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ func test2() {
7878
takes_closure { // ok.
7979
markUsed(b3)
8080
}
81+
82+
var b4 : Int?
83+
takes_closure { // ok.
84+
markUsed(b4!)
85+
}
86+
b4 = 7
8187

8288
// Structs
8389
var s1 : SomeStruct
@@ -1184,3 +1190,9 @@ func test22436880() {
11841190
x = 1
11851191
bug22436880(&x) // expected-error {{immutable value 'x' may not be passed inout}}
11861192
}
1193+
1194+
// sr-184
1195+
let x: String? // expected-note 2 {{constant defined here}}
1196+
print(x?.characters.count) // expected-error {{constant 'x' used before being initialized}}
1197+
print(x!) // expected-error {{constant 'x' used before being initialized}}
1198+

0 commit comments

Comments
 (0)