From 7e087d7e7735344a65cc58c03a65ef3b2279f995 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Wed, 10 Sep 2025 15:05:04 -0700 Subject: [PATCH 1/2] Don't assume next block has instructions --- Python/flowgraph.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 18594ca2f44c0f..475f5b16b792fd 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -3617,7 +3617,10 @@ propagate_line_numbers(basicblock *entryblock) { } if (is_jump(last)) { basicblock *target = last->i_target; - if (target->b_predecessors == 1) { + while (target->b_iused == 0 && target->b_predecessors == 1) { + target = target->b_next; + } + if (target->b_predecessors == 1 && target->b_iused > 0) { if (target->b_instr[0].i_loc.lineno == NO_LOCATION.lineno) { target->b_instr[0].i_loc = prev_location; } From fb9ea7e8511cb19a0c4b08744fd844d675a4d58b Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Mon, 15 Sep 2025 17:08:00 +0100 Subject: [PATCH 2/2] add test, tweak --- Lib/test/test_compile.py | 11 +++++++++++ Python/flowgraph.c | 31 +++++++++++++++++-------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index e4483c26cfd41b..277a2a187543d4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1615,6 +1615,17 @@ def test_remove_redundant_nop_edge_case(self): def f(): a if (1 if b else c) else d + def test_lineno_propagation_empty_blocks(self): + # Smoke test. See gh-138714. + def f(): + while name: + try: + break + except: + pass + else: + 1 if 1 else 1 + def test_global_declaration_in_except_used_in_else(self): # See gh-111123 code = textwrap.dedent("""\ diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 475f5b16b792fd..a43f8b45b8775f 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -3591,8 +3591,19 @@ duplicate_exits_without_lineno(cfg_builder *g) * Also reduces the size of the line number table, * but has no impact on the generated line number events. */ + +static inline void +maybe_propagate_location(basicblock *b, int i, location loc) +{ + assert(b->b_iused > i); + if (b->b_instr[i].i_loc.lineno == NO_LOCATION.lineno) { + b->b_instr[i].i_loc = loc; + } +} + static void -propagate_line_numbers(basicblock *entryblock) { +propagate_line_numbers(basicblock *entryblock) +{ for (basicblock *b = entryblock; b != NULL; b = b->b_next) { cfg_instr *last = basicblock_last_instr(b); if (last == NULL) { @@ -3601,18 +3612,12 @@ propagate_line_numbers(basicblock *entryblock) { location prev_location = NO_LOCATION; for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_loc.lineno == NO_LOCATION.lineno) { - b->b_instr[i].i_loc = prev_location; - } - else { - prev_location = b->b_instr[i].i_loc; - } + maybe_propagate_location(b, i, prev_location); + prev_location = b->b_instr[i].i_loc; } if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) { if (b->b_next->b_iused > 0) { - if (b->b_next->b_instr[0].i_loc.lineno == NO_LOCATION.lineno) { - b->b_next->b_instr[0].i_loc = prev_location; - } + maybe_propagate_location(b->b_next, 0, prev_location); } } if (is_jump(last)) { @@ -3620,10 +3625,8 @@ propagate_line_numbers(basicblock *entryblock) { while (target->b_iused == 0 && target->b_predecessors == 1) { target = target->b_next; } - if (target->b_predecessors == 1 && target->b_iused > 0) { - if (target->b_instr[0].i_loc.lineno == NO_LOCATION.lineno) { - target->b_instr[0].i_loc = prev_location; - } + if (target->b_predecessors == 1) { + maybe_propagate_location(target, 0, prev_location); } } }