Skip to content

Commit ea5c627

Browse files
authored
Unrolled build for rust-lang#121784
Rollup merge of rust-lang#121784 - Zalathar:if-or-converge, r=Nadrieril Make the success arms of `if lhs || rhs` meet up in a separate block Extracted from rust-lang#118305, where this is necessary to avoid introducing a bug when injecting marker statements into the then/else arms. --- In the previous code (rust-lang#111752), the success block of `lhs` would jump directly to the success block of `rhs`. However, `rhs_success_block` could already contain statements that are specific to the RHS, and the direct goto causes them to be executed in the LHS success path as well. This patch therefore creates a fresh block that the LHS and RHS success blocks can both jump to. --- I think the reason we currently get away with this is that `rhs_success_block` usually doesn't contain anything other than StorageDead statements for locals used by the RHS, and those statements don't seem to cause problems in the LHS success path (which never makes those locals live). But if we start adding meaningful statements for branch coverage (or MC/DC coverage), it's important to keep the LHS and RHS blocks separate.
2 parents 17edace + a7832b1 commit ea5c627

File tree

3 files changed

+64
-50
lines changed

3 files changed

+64
-50
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
9393
variable_source_info,
9494
true,
9595
));
96-
this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block);
97-
rhs_success_block.unit()
96+
97+
// Make the LHS and RHS success arms converge to a common block.
98+
// (We can't just make LHS goto RHS, because `rhs_success_block`
99+
// might contain statements that we don't want on the LHS path.)
100+
let success_block = this.cfg.start_new_block();
101+
this.cfg.goto(lhs_success_block, variable_source_info, success_block);
102+
this.cfg.goto(rhs_success_block, variable_source_info, success_block);
103+
success_block.unit()
98104
}
99105
ExprKind::Unary { op: UnOp::Not, arg } => {
100106
let local_scope = this.local_scope();

tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir

+41-37
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn test_complex() -> () {
1919
bb0: {
2020
StorageLive(_1);
2121
StorageLive(_2);
22-
_2 = E::f() -> [return: bb1, unwind: bb37];
22+
_2 = E::f() -> [return: bb1, unwind: bb38];
2323
}
2424

2525
bb1: {
@@ -34,7 +34,7 @@ fn test_complex() -> () {
3434
}
3535

3636
bb3: {
37-
goto -> bb22;
37+
goto -> bb23;
3838
}
3939

4040
bb4: {
@@ -51,7 +51,7 @@ fn test_complex() -> () {
5151

5252
bb7: {
5353
StorageLive(_4);
54-
_4 = always_true() -> [return: bb8, unwind: bb37];
54+
_4 = always_true() -> [return: bb8, unwind: bb38];
5555
}
5656

5757
bb8: {
@@ -73,7 +73,7 @@ fn test_complex() -> () {
7373
}
7474

7575
bb11: {
76-
drop(_7) -> [return: bb13, unwind: bb37];
76+
drop(_7) -> [return: bb13, unwind: bb38];
7777
}
7878

7979
bb12: {
@@ -83,11 +83,11 @@ fn test_complex() -> () {
8383
bb13: {
8484
StorageDead(_7);
8585
StorageDead(_6);
86-
goto -> bb19;
86+
goto -> bb20;
8787
}
8888

8989
bb14: {
90-
drop(_7) -> [return: bb15, unwind: bb37];
90+
drop(_7) -> [return: bb15, unwind: bb38];
9191
}
9292

9393
bb15: {
@@ -107,106 +107,110 @@ fn test_complex() -> () {
107107
}
108108

109109
bb17: {
110-
drop(_10) -> [return: bb19, unwind: bb37];
110+
drop(_10) -> [return: bb19, unwind: bb38];
111111
}
112112

113113
bb18: {
114-
goto -> bb20;
114+
goto -> bb21;
115115
}
116116

117117
bb19: {
118118
StorageDead(_10);
119119
StorageDead(_9);
120-
_1 = const ();
121-
goto -> bb23;
120+
goto -> bb20;
122121
}
123122

124123
bb20: {
125-
drop(_10) -> [return: bb21, unwind: bb37];
124+
_1 = const ();
125+
goto -> bb24;
126126
}
127127

128128
bb21: {
129-
StorageDead(_10);
130-
StorageDead(_9);
131-
goto -> bb22;
129+
drop(_10) -> [return: bb22, unwind: bb38];
132130
}
133131

134132
bb22: {
135-
_1 = const ();
133+
StorageDead(_10);
134+
StorageDead(_9);
136135
goto -> bb23;
137136
}
138137

139138
bb23: {
139+
_1 = const ();
140+
goto -> bb24;
141+
}
142+
143+
bb24: {
140144
StorageDead(_8);
141145
StorageDead(_5);
142146
StorageDead(_4);
143147
StorageDead(_2);
144148
StorageDead(_1);
145149
StorageLive(_11);
146-
_11 = always_true() -> [return: bb24, unwind: bb37];
147-
}
148-
149-
bb24: {
150-
switchInt(move _11) -> [0: bb26, otherwise: bb25];
150+
_11 = always_true() -> [return: bb25, unwind: bb38];
151151
}
152152

153153
bb25: {
154-
goto -> bb35;
154+
switchInt(move _11) -> [0: bb27, otherwise: bb26];
155155
}
156156

157157
bb26: {
158-
goto -> bb27;
158+
goto -> bb36;
159159
}
160160

161161
bb27: {
162-
StorageLive(_12);
163-
_12 = E::f() -> [return: bb28, unwind: bb37];
162+
goto -> bb28;
164163
}
165164

166165
bb28: {
167-
PlaceMention(_12);
168-
_13 = discriminant(_12);
169-
switchInt(move _13) -> [1: bb32, otherwise: bb30];
166+
StorageLive(_12);
167+
_12 = E::f() -> [return: bb29, unwind: bb38];
170168
}
171169

172170
bb29: {
173-
FakeRead(ForMatchedPlace(None), _12);
174-
unreachable;
171+
PlaceMention(_12);
172+
_13 = discriminant(_12);
173+
switchInt(move _13) -> [1: bb33, otherwise: bb31];
175174
}
176175

177176
bb30: {
178-
goto -> bb35;
177+
FakeRead(ForMatchedPlace(None), _12);
178+
unreachable;
179179
}
180180

181181
bb31: {
182-
goto -> bb29;
182+
goto -> bb36;
183183
}
184184

185185
bb32: {
186-
falseEdge -> [real: bb34, imaginary: bb30];
186+
goto -> bb30;
187187
}
188188

189189
bb33: {
190-
goto -> bb30;
190+
falseEdge -> [real: bb35, imaginary: bb31];
191191
}
192192

193193
bb34: {
194-
_0 = const ();
195-
goto -> bb36;
194+
goto -> bb31;
196195
}
197196

198197
bb35: {
199198
_0 = const ();
200-
goto -> bb36;
199+
goto -> bb37;
201200
}
202201

203202
bb36: {
203+
_0 = const ();
204+
goto -> bb37;
205+
}
206+
207+
bb37: {
204208
StorageDead(_11);
205209
StorageDead(_12);
206210
return;
207211
}
208212

209-
bb37 (cleanup): {
213+
bb38 (cleanup): {
210214
resume;
211215
}
212216
}

tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir

+15-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn test_or() -> () {
2020
}
2121

2222
bb1: {
23-
drop(_3) -> [return: bb3, unwind: bb12];
23+
drop(_3) -> [return: bb3, unwind: bb13];
2424
}
2525

2626
bb2: {
@@ -30,11 +30,11 @@ fn test_or() -> () {
3030
bb3: {
3131
StorageDead(_3);
3232
StorageDead(_2);
33-
goto -> bb8;
33+
goto -> bb9;
3434
}
3535

3636
bb4: {
37-
drop(_3) -> [return: bb5, unwind: bb12];
37+
drop(_3) -> [return: bb5, unwind: bb13];
3838
}
3939

4040
bb5: {
@@ -50,38 +50,42 @@ fn test_or() -> () {
5050
}
5151

5252
bb6: {
53-
drop(_6) -> [return: bb8, unwind: bb12];
53+
drop(_6) -> [return: bb8, unwind: bb13];
5454
}
5555

5656
bb7: {
57-
goto -> bb9;
57+
goto -> bb10;
5858
}
5959

6060
bb8: {
6161
StorageDead(_6);
6262
StorageDead(_5);
63-
_0 = const ();
64-
goto -> bb11;
63+
goto -> bb9;
6564
}
6665

6766
bb9: {
68-
drop(_6) -> [return: bb10, unwind: bb12];
67+
_0 = const ();
68+
goto -> bb12;
6969
}
7070

7171
bb10: {
72+
drop(_6) -> [return: bb11, unwind: bb13];
73+
}
74+
75+
bb11: {
7276
StorageDead(_6);
7377
StorageDead(_5);
7478
_0 = const ();
75-
goto -> bb11;
79+
goto -> bb12;
7680
}
7781

78-
bb11: {
82+
bb12: {
7983
StorageDead(_4);
8084
StorageDead(_1);
8185
return;
8286
}
8387

84-
bb12 (cleanup): {
88+
bb13 (cleanup): {
8589
resume;
8690
}
8791
}

0 commit comments

Comments
 (0)