summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-09-28 19:33:28 (GMT)
committerGitHub <noreply@github.com>2023-09-28 19:33:28 (GMT)
commitf580edcc6a4c528020afe46c753db713474acad6 (patch)
treeccc20e518bdb608d352ee87cfbd0c610c1973011
parentb14f0ab51cb4851b25935279617e388456dcf716 (diff)
downloadcpython-f580edcc6a4c528020afe46c753db713474acad6.zip
cpython-f580edcc6a4c528020afe46c753db713474acad6.tar.gz
cpython-f580edcc6a4c528020afe46c753db713474acad6.tar.bz2
gh-109889: fix compiler's redundant NOP detection to look past NOPs with no lineno when looking for the next instruction's lineno (#109987)
-rw-r--r--Lib/test/test_compile.py5
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst2
-rw-r--r--Python/flowgraph.c12
3 files changed, 18 insertions, 1 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 53e3e8f..c4452e3 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1278,6 +1278,11 @@ class TestSpecifics(unittest.TestCase):
while x:
0 if 1 else 0
+ def test_remove_redundant_nop_edge_case(self):
+ # See gh-109889
+ def f():
+ a if (1 if b else c) else d
+
@requires_debug_ranges()
class TestSourcePositions(unittest.TestCase):
# Ensure that compiled code snippets have correct line and column numbers
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst
new file mode 100644
index 0000000..8be373f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst
@@ -0,0 +1,2 @@
+Fix the compiler's redundant NOP detection algorithm to skip over NOPs with
+no line number when looking for the next instruction's lineno.
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 9fe387c..e89ad39 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -1017,7 +1017,17 @@ remove_redundant_nops(basicblock *bb) {
}
/* or if last instruction in BB and next BB has same line number */
if (next) {
- if (lineno == next->b_instr[0].i_loc.lineno) {
+ location next_loc = NO_LOCATION;
+ for (int next_i=0; next_i < next->b_iused; next_i++) {
+ cfg_instr *instr = &next->b_instr[next_i];
+ if (instr->i_opcode == NOP && instr->i_loc.lineno == NO_LOCATION.lineno) {
+ /* Skip over NOPs without location, they will be removed */
+ continue;
+ }
+ next_loc = instr->i_loc;
+ break;
+ }
+ if (lineno == next_loc.lineno) {
continue;
}
}