Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Guarantee that line number is set for returns.
  • Loading branch information
markshannon committed May 12, 2021
commit 23a5a31d6f7fdc5bd2497dbdb50cdeba7ee2cc57
1 change: 1 addition & 0 deletions Lib/test/test_sys_settrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,7 @@ async def test_no_jump_forwards_into_async_for_block(output):
output.append(1)
async for i in asynciter([1, 2]):
output.append(3)
pass

@jump_test(3, 2, [2, 2], (ValueError, 'into'))
def test_no_jump_backwards_into_for_block(output):
Expand Down
31 changes: 31 additions & 0 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -6960,6 +6960,36 @@ insert_generator_prefix(struct compiler *c, basicblock *entryblock) {
return 0;
}

/* Make sure that all returns have a line number, even if early passes
* have failed to propagate a correct line number.
* The resulting line number may not be correct according to PEP 626,
* but should be "good enough", and no worse than in older versions. */
static void
guarantee_lineno_for_exits(struct assembler *a, int firstlineno) {
int lineno = firstlineno;
assert(lineno > 0);
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
if (b->b_iused == 0) {
continue;
}
struct instr *last = &b->b_instr[b->b_iused-1];
if (last->i_lineno < 0) {
/* A return in a block by itself can't have a linenumber, or
* we can mess up frame.setlineno */
if (last->i_opcode == RETURN_VALUE)
{
for (int i = 0; i < b->b_iused; i++) {
assert(b->b_instr[i].i_lineno < 0);
b->b_instr[i].i_lineno = lineno;
}
}
}
else {
lineno = last->i_lineno;
}
}
}

static PyCodeObject *
assemble(struct compiler *c, int addNone)
{
Expand Down Expand Up @@ -7022,6 +7052,7 @@ assemble(struct compiler *c, int addNone)
if (optimize_cfg(c, &a, consts)) {
goto error;
}
guarantee_lineno_for_exits(&a, c->u->u_firstlineno);

/* Can't modify the bytecode after computing jump offsets. */
assemble_jump_offsets(&a, c);
Expand Down