Skip to content

Commit 5a2465e

Browse files
authored
Merge pull request swiftlang#68705 from hamishknight/oh-hi-mark
2 parents 156fd08 + 6960756 commit 5a2465e

File tree

4 files changed

+190
-73
lines changed

4 files changed

+190
-73
lines changed

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,15 +1693,8 @@ std::unique_ptr<Initialization> SILGenFunction::getSingleValueStmtInit(Expr *E)
16931693
// SingleValueStmtExpr initialization.
16941694
if (!SingleValueStmtInitStack.back().Exprs.contains(E))
16951695
return nullptr;
1696-
1697-
// This won't give us a useful diagnostic if the result doesn't end up
1698-
// initialized ("variable '<unknown>' used before being initialized"), but it
1699-
// will at least catch a potential miscompile when the SIL verifier is
1700-
// disabled.
1696+
17011697
auto resultAddr = SingleValueStmtInitStack.back().InitializationBuffer;
1702-
resultAddr = B.createMarkUninitialized(
1703-
E, resultAddr, MarkUninitializedInst::Kind::Var);
1704-
17051698
return std::make_unique<KnownAddressInitialization>(resultAddr);
17061699
}
17071700

lib/SILGen/SILGenStmt.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,9 +833,20 @@ void StmtEmitter::visitYieldStmt(YieldStmt *S) {
833833

834834
void StmtEmitter::visitThenStmt(ThenStmt *S) {
835835
auto *E = S->getResult();
836-
auto init = SGF.getSingleValueStmtInit(E);
837836

838-
if (init && !E->getType()->isStructurallyUninhabited()) {
837+
// If we have an uninhabited type, we may not be able to use it for
838+
// initialization, since we allow the conversion of Never to any other type.
839+
// Instead, emit an ignored expression with an unreachable.
840+
if (E->getType()->isUninhabited()) {
841+
SGF.emitIgnoredExpr(E);
842+
SGF.B.createUnreachable(E);
843+
return;
844+
}
845+
846+
// Retrieve the initialization for the parent SingleValueStmtExpr. If we don't
847+
// have an init, we don't care about the result, emit an ignored expr. This is
848+
// the case if e.g the result is being converted to Void.
849+
if (auto init = SGF.getSingleValueStmtInit(E)) {
839850
SGF.emitExprInto(E, init.get());
840851
} else {
841852
SGF.emitIgnoredExpr(E);

test/SILGen/if_expr.swift

Lines changed: 84 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,24 @@ func foo() -> Int {
66
}
77

88
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr3fooSiyF : $@convention(thin) () -> Int
9-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $Int
9+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
1010
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
1111
//
1212
// CHECK: [[TRUEBB]]:
13-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*Int
1413
// CHECK: [[ONE_BUILTIN:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 1
1514
// CHECK: [[ONE:%[0-9]+]] = apply {{%[0-9]+}}([[ONE_BUILTIN]], {{%[0-9]+}}) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
1615
// CHECK: store [[ONE]] to [trivial] [[RESULT]] : $*Int
1716
// CHECK: br [[EXITBB:bb[0-9]+]]
1817
//
1918
// CHECK: [[FALSEBB]]:
20-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*Int
2119
// CHECK: [[TWO_BUILTIN:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 2
2220
// CHECK: [[TWO:%[0-9]+]] = apply {{%[0-9]+}}([[TWO_BUILTIN]], {{%[0-9]+}}) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
2321
// CHECK: store [[TWO]] to [trivial] [[RESULT]] : $*Int
2422
// CHECK: br [[EXITBB]]
2523
//
2624
// CHECK: [[EXITBB]]:
27-
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT_STORAGE]] : $*Int
28-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
25+
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
26+
// CHECK: dealloc_stack [[RESULT]] : $*Int
2927
// CHECK: return [[VAL]] : $Int
3028

3129
class C {}
@@ -36,25 +34,23 @@ func bar(_ x: C) -> C {
3634

3735
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr3baryAA1CCADF : $@convention(thin) (@guaranteed C) -> @owned C
3836
// CHECK: bb0([[CPARAM:%[0-9]+]] : @guaranteed $C):
39-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $C
37+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $C
4038
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
4139
//
4240
// CHECK: [[TRUEBB]]:
43-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*C
4441
// CHECK: [[C:%[0-9]+]] = copy_value [[CPARAM]] : $C
4542
// CHECK: store [[C]] to [init] [[RESULT]] : $*C
4643
// CHECK: br [[EXITBB:bb[0-9]+]]
4744
//
4845
// CHECK: [[FALSEBB]]:
49-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*C
5046
// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s7if_expr1CCACycfC : $@convention(method) (@thick C.Type) -> @owned C
5147
// CHECK: [[C:%[0-9]+]] = apply [[CTOR]]({{%[0-9]+}}) : $@convention(method) (@thick C.Type) -> @owned C
5248
// CHECK: store [[C]] to [init] [[RESULT]] : $*C
5349
// CHECK: br [[EXITBB]]
5450
//
5551
// CHECK: [[EXITBB]]:
56-
// CHECK: [[VAL:%[0-9]+]] = load [take] [[RESULT_STORAGE]] : $*C
57-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*C
52+
// CHECK: [[VAL:%[0-9]+]] = load [take] [[RESULT]] : $*C
53+
// CHECK: dealloc_stack [[RESULT]] : $*C
5854
// CHECK: return [[VAL]] : $C
5955

6056
struct Err: Error {}
@@ -70,7 +66,7 @@ func baz() throws -> Int {
7066
}
7167

7268
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr3bazSiyKF : $@convention(thin) () -> (Int, @error any Error)
73-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $Int
69+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
7470
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
7571
//
7672
// CHECK: [[FALSEBB]]:
@@ -83,33 +79,32 @@ func baz() throws -> Int {
8379
// CHECK: br [[EXITBB:bb[0-9]+]]
8480
//
8581
// CHECK: [[EXITBB]]:
86-
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT_STORAGE]] : $*Int
87-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
82+
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
83+
// CHECK: dealloc_stack [[RESULT]] : $*Int
8884
// CHECK: return [[VAL]] : $Int
8985

9086
func qux() throws -> Int {
9187
if .random() { 0 } else { try baz() }
9288
}
9389

9490
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr3quxSiyKF : $@convention(thin) () -> (Int, @error any Error)
95-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $Int
91+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
9692
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
9793
//
9894
// CHECK: [[FALSEBB]]:
99-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*Int
10095
// CHECK: try_apply {{%[0-9]+}}() : $@convention(thin) () -> (Int, @error any Error), normal [[NORMALBB:bb[0-9]+]], error [[ERRORBB:bb[0-9]+]]
10196
//
10297
// CHECK: [[NORMALBB]]([[BAZVAL:%[0-9]+]] : $Int):
10398
// CHECK: store [[BAZVAL]] to [trivial] [[RESULT]] : $*Int
10499
// CHECK: br [[EXITBB:bb[0-9]+]]
105100
//
106101
// CHECK: [[EXITBB]]:
107-
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT_STORAGE]] : $*Int
108-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
102+
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
103+
// CHECK: dealloc_stack [[RESULT]] : $*Int
109104
// CHECK: return [[VAL]] : $Int
110105
//
111106
// CHECK: [[ERRORBB]]([[ERR:%[0-9]+]] : @owned $any Error):
112-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
107+
// CHECK: dealloc_stack [[RESULT]] : $*Int
113108
// CHECK: throw [[ERR]] : $any Error
114109

115110
func optionalVoidCrash() {
@@ -141,24 +136,23 @@ func testClosure() throws -> Int {
141136
}
142137

143138
// CHECK-LABEL: sil private [ossa] @$s7if_expr11testClosureSiyKFSiyKcfU_ : $@convention(thin) () -> (Int, @error any Error)
144-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $Int
139+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
145140
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
146141
//
147142
// CHECK: [[FALSEBB]]:
148-
// CHECK: [[RESULT:%[0-9]+]] = mark_uninitialized [var] [[RESULT_STORAGE]] : $*Int
149143
// CHECK: try_apply {{%[0-9]+}}() : $@convention(thin) () -> (Int, @error any Error), normal [[NORMALBB:bb[0-9]+]], error [[ERRORBB:bb[0-9]+]]
150144
//
151145
// CHECK: [[NORMALBB]]([[BAZVAL:%[0-9]+]] : $Int):
152146
// CHECK: store [[BAZVAL]] to [trivial] [[RESULT]] : $*Int
153147
// CHECK: br [[EXITBB:bb[0-9]+]]
154148
//
155149
// CHECK: [[EXITBB]]:
156-
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT_STORAGE]] : $*Int
157-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
150+
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
151+
// CHECK: dealloc_stack [[RESULT]] : $*Int
158152
// CHECK: return [[VAL]] : $Int
159153
//
160154
// CHECK: [[ERRORBB]]([[ERR:%[0-9]+]] : @owned $any Error):
161-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
155+
// CHECK: dealloc_stack [[RESULT]] : $*Int
162156
// CHECK: throw [[ERR]] : $any Error
163157

164158
func testNested() throws -> Int {
@@ -174,7 +168,7 @@ func testNested() throws -> Int {
174168
}
175169

176170
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr10testNestedSiyKF : $@convention(thin) () -> (Int, @error any Error)
177-
// CHECK: [[RESULT_STORAGE:%[0-9]+]] = alloc_stack $Int
171+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
178172
// CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], [[FALSEBB:bb[0-9]+]]
179173
//
180174
// CHECK: [[FALSEBB]]:
@@ -187,8 +181,8 @@ func testNested() throws -> Int {
187181
// CHECK: br [[EXITBB:bb[0-9]+]]
188182
//
189183
// CHECK: [[EXITBB]]:
190-
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT_STORAGE]] : $*Int
191-
// CHECK: dealloc_stack [[RESULT_STORAGE]] : $*Int
184+
// CHECK: [[VAL:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
185+
// CHECK: dealloc_stack [[RESULT]] : $*Int
192186
// CHECK: return [[VAL]] : $Int
193187

194188
func testVar() -> Int {
@@ -509,6 +503,70 @@ func testNever2() -> Never {
509503
if .random() { fatalError() } else { fatalError() }
510504
}
511505

506+
func testNever3() -> Int {
507+
if .random() {
508+
fatalError()
509+
} else {
510+
0
511+
}
512+
}
513+
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr10testNever3SiyF : $@convention(thin) () -> Int
514+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $Int
515+
// CHECK: cond_br {{%[0-9]+}}, [[BB_TRUE:bb[0-9]+]], [[BB_FALSE:bb[0-9]+]]
516+
//
517+
// CHECK: [[BB_TRUE]]:
518+
// CHECK: function_ref fatalError(_:file:line:)
519+
// CHECK: unreachable
520+
//
521+
// CHECK: [[BB_FALSE]]:
522+
// CHECK: store {{%[0-9]+}} to [trivial] [[RESULT]] : $*Int
523+
// CHECK: [[RET:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
524+
// CHECK: dealloc_stack [[RESULT]] : $*Int
525+
// CHECK: return [[RET]]
526+
527+
func never() -> Never { fatalError() }
528+
529+
func testNever4() -> Int {
530+
if .random() {
531+
never()
532+
} else {
533+
0
534+
}
535+
}
536+
537+
func neverTuple() -> (Never, Int) { fatalError() }
538+
539+
func testNever5() -> (Never, Int) {
540+
if .random() {
541+
neverTuple()
542+
} else {
543+
(never(), 0)
544+
}
545+
}
546+
// CHECK-LABEL: sil hidden [ossa] @$s7if_expr10testNever5s5NeverO_SityF : $@convention(thin) () -> (Never, Int)
547+
// CHECK: [[RESULT:%[0-9]+]] = alloc_stack $(Never, Int)
548+
// CHECK: cond_br {{%[0-9]+}}, [[BB_TRUE:bb[0-9]+]], [[BB_FALSE:bb[0-9]+]]
549+
//
550+
// CHECK: [[BB_TRUE]]:
551+
// CHECK: [[ELT_0:%[0-9]+]] = tuple_element_addr [[RESULT]] : $*(Never, Int), 0
552+
// CHECK: [[ELT_1:%[0-9]+]] = tuple_element_addr [[RESULT]] : $*(Never, Int), 1
553+
// CHECK: ([[RET_0:%[0-9]+]], [[RET_1:%[0-9]+]]) = destructure_tuple {{%[0-9]+}} : $(Never, Int)
554+
// CHECK: store [[RET_0]] to [trivial] [[ELT_0]] : $*Never
555+
// CHECK: store [[RET_1]] to [trivial] [[ELT_1]] : $*Int
556+
// CHECK: br [[BB_EXIT:bb[0-9]+]]
557+
//
558+
// CHECK: [[BB_FALSE]]:
559+
// CHECK: [[ELT_0:%[0-9]+]] = tuple_element_addr [[RESULT]] : $*(Never, Int), 0
560+
// CHECK: [[ELT_1:%[0-9]+]] = tuple_element_addr [[RESULT]] : $*(Never, Int), 1
561+
// CHECK: store {{%[0-9]+}} to [trivial] [[ELT_0]] : $*Never
562+
// CHECK: store {{%[0-9]+}} to [trivial] [[ELT_1]] : $*Int
563+
// CHECK: br [[BB_EXIT:bb[0-9]+]]
564+
//
565+
// CHECK: [[BB_EXIT]]:
566+
// CHECK: dealloc_stack [[RESULT]] : $*(Never, Int)
567+
// CHECK: [[RET:%[0-9]+]] = tuple ({{%[0-9]+}} : $Never, {{%[0-9]+}} : $Int)
568+
// CHECK: return [[RET]]
569+
512570
func testCaptureList() -> Int {
513571
let fn = { [x = if .random() { 0 } else { 1 }] in x }
514572
return fn()

0 commit comments

Comments
 (0)