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.

7db3c48833 (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.
This commit is contained in:
Gregory P. Smith 2018-11-08 17:55:07 -08:00 committed by GitHub
parent fd512d7645
commit 49fa4a9f1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 10 deletions

View file

@ -1,3 +1,4 @@
import dis
import math
import os
import unittest
@ -621,6 +622,24 @@ if 1:
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.