-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-38115: fix invalid lnotab after optimization #15970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…have invalid bytecode offsets when the optimizer got rid of the last line(s) of a function. Also fix a bug where the optimizer bails out of optimization but leaves the lnotab modified.
@markshannon might also be interested in this, I guess ;-P |
Looks like the new assertion is getting triggered by code in test_scope, I'm digging into it. |
…ix the assert in the face of empty bytecode.
The assert didn't consider empty bytecode, that's now fixed. |
After some consideration, this is the wrong fix. See the test_pdb failure; replacing entries for past the end to the end makes consumers of lnotab think the last opcode of the function is part of the removed lines. Instead, what we should do is truncate lnotab. Unfortunately we can't do that, because PyCode_Optimize() is passed the lnotab as a PyBytes object, and can't resize it (because that may move it, which means the caller's object is invalid.) Considering the peephole optimizer is likely to go away in 3.9, and this bug isn't that harmful (it doesn't confuse pdb or coverage), we should probably just document that the lnotab can contain invalid bytecode offsets and ignore it for now. |
Fix bpo-38115, a bug in the peephole optimizer that caused lnotab to have invalid bytecode offsets when the optimizer got rid of the last line(s) of a function. Also fix a bug where the optimizer bails out of optimization but leaves the lnotab modified. This is a very old bug, but before 3.8 the optimizer is more likely to successfully optimize away the last line of a function.
These don't change the bytecode that's generated, but they do change the code objects (the co_lnotab attribute), so though they theoretically affect Python 3.7 and earlier, we shouldn't backport this beyond 3.8. (Also, if you want to verify this manually, don't forget to touch the .py file or delete the .pyc file... not that I'm speaking of personal experience or anything.)
https://bugs.python.org/issue38115