bpo-35193: Fix an off by one error in the RETURN_VALUE case. (GH-10418)
Fix an off by one error in the peephole optimizer when checking for unreachable code beyond a return.
Do a bounds check within find_op so it can return before going past the end as a safety measure.
https://github.com/python/cpython/commit/7db3c488335168993689ddae5914a28e16188447GH-diff-a33329ae6ae0bb295d742f0caf93c137
introduced this off by one error while fixing another one nearby.
This bug was shipped in all Python 3.6 and 3.7 releases.
The included unittest won't fail unless you do a clang msan build.
(cherry picked from commit 49fa4a9f1ef387e16596f271414c855339eadf09)
Co-authored-by: Gregory P. Smith <greg@krypto.org>
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index d8a57e5..5ac1c5f 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1,3 +1,4 @@
+import dis
import math
import os
import unittest
@@ -621,6 +622,24 @@
self.check_constant(f1, frozenset({0}))
self.assertTrue(f1(0))
+ # This is a regression test for a CPython specific peephole optimizer
+ # implementation bug present in a few releases. It's assertion verifies
+ # that peephole optimization was actually done though that isn't an
+ # indication of the bugs presence or not (crashing is).
+ @support.cpython_only
+ def test_peephole_opt_unreachable_code_array_access_in_bounds(self):
+ """Regression test for issue35193 when run under clang msan."""
+ def unused_code_at_end():
+ return 3
+ raise RuntimeError("unreachable")
+ # The above function definition will trigger the out of bounds
+ # bug in the peephole optimizer as it scans opcodes past the
+ # RETURN_VALUE opcode. This does not always crash an interpreter.
+ # When you build with the clang memory sanitizer it reliably aborts.
+ self.assertEqual(
+ 'RETURN_VALUE',
+ list(dis.get_instructions(unused_code_at_end))[-1].opname)
+
def test_dont_merge_constants(self):
# Issue #25843: compile() must not merge constants which are equal
# but have a different type.