@@ -156,11 +156,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
156
156
//
157
157
// If `opt_cond_expr` is `None`, then the graph is somewhat simplified:
158
158
//
159
- // [block] --> [loop_block / body_block ] ~~> [body_block_end] [exit_block]
160
- // ^ |
161
- // | |
162
- // +--------------------------+
159
+ // [block] --> [loop_block] ~~> [loop_block_end]
160
+ // | ^ |
161
+ // false link | |
162
+ // | +-------------------+
163
+ // v
164
+ // [cleanup_block]
163
165
//
166
+ // The false link is required in case something results in
167
+ // unwinding through the body.
164
168
165
169
let loop_block = this. cfg . start_new_block ( ) ;
166
170
let exit_block = this. cfg . start_new_block ( ) ;
@@ -174,6 +178,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
174
178
move |this| {
175
179
// conduct the test, if necessary
176
180
let body_block;
181
+ let out_terminator;
177
182
if let Some ( cond_expr) = opt_cond_expr {
178
183
let loop_block_end;
179
184
let cond = unpack ! (
@@ -187,8 +192,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
187
192
// we have to do it; this overwrites any `break`-assigned value but it's
188
193
// always `()` anyway
189
194
this. cfg . push_assign_unit ( exit_block, source_info, destination) ;
195
+
196
+ out_terminator = TerminatorKind :: Goto { target : loop_block } ;
190
197
} else {
191
198
body_block = loop_block;
199
+ let diverge_cleanup = this. diverge_cleanup ( ) ;
200
+ out_terminator = TerminatorKind :: FalseUnwind {
201
+ real_target : loop_block,
202
+ unwind : Some ( diverge_cleanup)
203
+ }
192
204
}
193
205
194
206
// The “return” value of the loop body must always be an unit. We therefore
@@ -197,7 +209,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
197
209
// Execute the body, branching back to the test.
198
210
let body_block_end = unpack ! ( this. into( & tmp, body_block, body) ) ;
199
211
this. cfg . terminate ( body_block_end, source_info,
200
- TerminatorKind :: Goto { target : loop_block } ) ;
212
+ out_terminator ) ;
201
213
}
202
214
) ;
203
215
exit_block. unit ( )
0 commit comments