Skip to content

Commit 9ccf054

Browse files
authored
pythongh-109627: duplicated smalll exit blocks need to be assigned jump target labels (python#109630)
1 parent 14cdefa commit 9ccf054

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

Lib/test/test_compile.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,15 @@ def f():
12521252
return a, b
12531253
self.assertEqual(f(), (54, 96))
12541254

1255+
def test_duplicated_small_exit_block(self):
1256+
# See gh-109627
1257+
def f():
1258+
while element and something:
1259+
try:
1260+
return something
1261+
except:
1262+
pass
1263+
12551264

12561265
@requires_debug_ranges()
12571266
class TestSourcePositions(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix bug where the compiler does not assign a new jump target label to a
2+
duplicated small exit block.

Python/flowgraph.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -575,16 +575,23 @@ check_cfg(cfg_builder *g) {
575575
return SUCCESS;
576576
}
577577

578-
/* Calculate the actual jump target from the target_label */
579578
static int
580-
translate_jump_labels_to_targets(basicblock *entryblock)
579+
get_max_label(basicblock *entryblock)
581580
{
582-
int max_label = -1;
581+
int lbl = -1;
583582
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
584-
if (b->b_label.id > max_label) {
585-
max_label = b->b_label.id;
583+
if (b->b_label.id > lbl) {
584+
lbl = b->b_label.id;
586585
}
587586
}
587+
return lbl;
588+
}
589+
590+
/* Calculate the actual jump target from the target_label */
591+
static int
592+
translate_jump_labels_to_targets(basicblock *entryblock)
593+
{
594+
int max_label = get_max_label(entryblock);
588595
size_t mapsize = sizeof(basicblock *) * (max_label + 1);
589596
basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
590597
if (!label2block) {
@@ -2229,6 +2236,7 @@ is_exit_without_lineno(basicblock *b) {
22292236
return true;
22302237
}
22312238

2239+
22322240
/* PEP 626 mandates that the f_lineno of a frame is correct
22332241
* after a frame terminates. It would be prohibitively expensive
22342242
* to continuously update the f_lineno field at runtime,
@@ -2242,6 +2250,9 @@ static int
22422250
duplicate_exits_without_lineno(cfg_builder *g)
22432251
{
22442252
assert(no_empty_basic_blocks(g));
2253+
2254+
int next_lbl = get_max_label(g->g_entryblock) + 1;
2255+
22452256
/* Copy all exit blocks without line number that are targets of a jump.
22462257
*/
22472258
basicblock *entryblock = g->g_entryblock;
@@ -2260,6 +2271,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
22602271
target->b_predecessors--;
22612272
new_target->b_predecessors = 1;
22622273
new_target->b_next = target->b_next;
2274+
new_target->b_label.id = next_lbl++;
22632275
target->b_next = new_target;
22642276
}
22652277
}

0 commit comments

Comments
 (0)