Skip to content

Commit faa8003

Browse files
committed
gh-109627: duplicated smalll exit blocks need to be assigned jump target labels (#109630)
(cherry picked from commit 9ccf054)
1 parent 4a0c118 commit faa8003

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
@@ -1216,6 +1216,15 @@ def f(x, y, z):
12161216
return a
12171217
self.assertEqual(f("x", "y", "z"), "y")
12181218

1219+
def test_duplicated_small_exit_block(self):
1220+
# See gh-109627
1221+
def f():
1222+
while element and something:
1223+
try:
1224+
return something
1225+
except:
1226+
pass
1227+
12191228

12201229
@requires_debug_ranges()
12211230
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
@@ -562,16 +562,23 @@ check_cfg(cfg_builder *g) {
562562
return SUCCESS;
563563
}
564564

565-
/* Calculate the actual jump target from the target_label */
566565
static int
567-
translate_jump_labels_to_targets(basicblock *entryblock)
566+
get_max_label(basicblock *entryblock)
568567
{
569-
int max_label = -1;
568+
int lbl = -1;
570569
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
571-
if (b->b_label.id > max_label) {
572-
max_label = b->b_label.id;
570+
if (b->b_label.id > lbl) {
571+
lbl = b->b_label.id;
573572
}
574573
}
574+
return lbl;
575+
}
576+
577+
/* Calculate the actual jump target from the target_label */
578+
static int
579+
translate_jump_labels_to_targets(basicblock *entryblock)
580+
{
581+
int max_label = get_max_label(entryblock);
575582
size_t mapsize = sizeof(basicblock *) * (max_label + 1);
576583
basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
577584
if (!label2block) {
@@ -2035,6 +2042,7 @@ is_exit_without_lineno(basicblock *b) {
20352042
return true;
20362043
}
20372044

2045+
20382046
/* PEP 626 mandates that the f_lineno of a frame is correct
20392047
* after a frame terminates. It would be prohibitively expensive
20402048
* to continuously update the f_lineno field at runtime,
@@ -2048,6 +2056,9 @@ static int
20482056
duplicate_exits_without_lineno(cfg_builder *g)
20492057
{
20502058
assert(no_empty_basic_blocks(g));
2059+
2060+
int next_lbl = get_max_label(g->g_entryblock) + 1;
2061+
20512062
/* Copy all exit blocks without line number that are targets of a jump.
20522063
*/
20532064
basicblock *entryblock = g->g_entryblock;
@@ -2066,6 +2077,7 @@ duplicate_exits_without_lineno(cfg_builder *g)
20662077
target->b_predecessors--;
20672078
new_target->b_predecessors = 1;
20682079
new_target->b_next = target->b_next;
2080+
new_target->b_label.id = next_lbl++;
20692081
target->b_next = new_target;
20702082
}
20712083
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy