diff options
author | Mark Shannon <mark@hotpy.org> | 2021-05-12 11:25:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-12 11:25:44 +0100 |
commit | cb6f3d7163c611a7772da8969475e47fbdd147af (patch) | |
tree | 85d0ea5fd1157be58589158d1aaf3a6ff32b3ea0 /Python/compile.c | |
parent | 6574334a68aa324394a6fd1f855ecbad20432b1e (diff) | |
download | cpython-cb6f3d7163c611a7772da8969475e47fbdd147af.tar.gz cpython-cb6f3d7163c611a7772da8969475e47fbdd147af.zip |
bpo-43933: Force RETURN_VALUE bytecodes to have line numbers (GH-26054)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/Python/compile.c b/Python/compile.c index 013ee4b6c84..071dabc825b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -7276,6 +7276,34 @@ 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) { + 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) { @@ -7338,6 +7366,7 @@ assemble(struct compiler *c, int addNone) if (optimize_cfg(c, &a, consts)) { goto error; } + guarantee_lineno_for_exits(&a, c->u->u_firstlineno); int maxdepth = stackdepth(c); if (maxdepth < 0) { |