From 9368b885e8ca616d247bbc59068d149dc022a037 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Mon, 25 Sep 2023 19:25:05 +0100 Subject: [PATCH] gh-109823: Adjust labels in compiler when removing an empty basic block which is a jump target (GH-109839) (cherry picked from commit d73c12b88c2275fd44e27c91c24f3ac85419d2b8) Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Lib/test/test_compile.py | 5 +++++ .../2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst | 2 ++ Python/flowgraph.c | 9 ++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 2e5763eb3d61e9..e377620a0c87b8 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1236,6 +1236,11 @@ def f(): else: 1 if 1 else 1 + def test_remove_empty_basic_block_with_jump_target_label(self): + # See gh-109823 + def f(x): + while x: + 0 if 1 else 0 @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst new file mode 100644 index 00000000000000..793c89f4445f54 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst @@ -0,0 +1,2 @@ +Fix bug where compiler does not adjust labels when removing an empty basic +block which is a jump target. diff --git a/Python/flowgraph.c b/Python/flowgraph.c index d19fe686d01c94..ccf078c7feab2d 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -922,6 +922,7 @@ eliminate_empty_basic_blocks(cfg_builder *g) { while(g->g_entryblock && g->g_entryblock->b_iused == 0) { g->g_entryblock = g->g_entryblock->b_next; } + int next_lbl = get_max_label(g->g_entryblock) + 1; for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { assert(b->b_iused > 0); for (int i = 0; i < b->b_iused; i++) { @@ -931,7 +932,13 @@ eliminate_empty_basic_blocks(cfg_builder *g) { while (target->b_iused == 0) { target = target->b_next; } - instr->i_target = target; + if (instr->i_target != target) { + if (!IS_LABEL(target->b_label)) { + target->b_label.id = next_lbl++; + } + instr->i_target = target; + instr->i_oparg = target->b_label.id; + } assert(instr->i_target && instr->i_target->b_iused > 0); } }