From e2fce3a8e77d33d52d47b567964ddebd6984a097 Mon Sep 17 00:00:00 2001 From: Brandt Bucher <brandtbucher@microsoft.com> Date: Wed, 20 Jul 2022 15:01:42 -0700 Subject: [PATCH] [3.11] GH-91409: Don't overwrite valid locations with NOP locations (GH-95067) (GH-95068) (cherry picked from commit 742d4614e1a645d765dbf76c19bd9a818239b1cb) --- Lib/test/test_compile.py | 38 +++++++++++++++++++ ...2-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst | 2 + Python/compile.c | 5 ++- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 80b32dee066..e22696499e2 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1166,6 +1166,44 @@ def test_multiline_assert_rewritten_as_method_call(self): tree.body[0] = new_node compile(tree, "<test>", "exec") + def test_push_null_load_global_positions(self): + source_template = """ + import abc, dis + import ast as art + + abc = None + dix = dis + ast = art + + def f(): + {} + """ + for body in [ + " abc.a()", + " art.a()", + " ast.a()", + " dis.a()", + " dix.a()", + " abc[...]()", + " art()()", + " (ast or ...)()", + " [dis]()", + " (dix + ...)()", + ]: + with self.subTest(body): + namespace = {} + source = textwrap.dedent(source_template.format(body)) + exec(source, namespace) + code = namespace["f"].__code__ + self.assertOpcodeSourcePositionIs( + code, + "LOAD_GLOBAL", + line=10, + end_line=10, + column=4, + end_column=7, + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst new file mode 100644 index 00000000000..2bc0d8224c6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst @@ -0,0 +1,2 @@ +Fix incorrect source location info caused by certain optimizations in the +bytecode compiler. diff --git a/Python/compile.c b/Python/compile.c index 3fe0930e7ae..e8acd859777 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -9045,7 +9045,10 @@ clean_basic_block(basicblock *bb) { /* or, if the next instruction has same line number or no line number */ if (src < bb->b_iused - 1) { int next_lineno = bb->b_instr[src+1].i_lineno; - if (next_lineno < 0 || next_lineno == lineno) { + if (next_lineno == lineno) { + continue; + } + if (next_lineno < 0) { COPY_INSTR_LOC(bb->b_instr[src], bb->b_instr[src+1]); continue; } -- GitLab