diff options
author | Mark Shannon <mark@hotpy.org> | 2021-06-03 15:45:58 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-03 15:45:58 (GMT) |
commit | 937cebc93b4922583218e0cbf0a9a14705a595b2 (patch) | |
tree | c1d1850a46f708810ab72827e8fe82b5e2921317 /Python/compile.c | |
parent | 4eed2821d40373345ed133b2b8d912fef59acab7 (diff) | |
download | cpython-937cebc93b4922583218e0cbf0a9a14705a595b2.zip cpython-937cebc93b4922583218e0cbf0a9a14705a595b2.tar.gz cpython-937cebc93b4922583218e0cbf0a9a14705a595b2.tar.bz2 |
bpo-44298: Fix line numbers for early exits in with statements. (GH-26513)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/Python/compile.c b/Python/compile.c index 2cbe1ec..03d522b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1796,7 +1796,6 @@ static int compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, int preserve_tos) { - int loc; switch (info->fb_type) { case WHILE_LOOP: case EXCEPTION_HANDLER: @@ -1850,7 +1849,6 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, case WITH: case ASYNC_WITH: - loc = c->u->u_lineno; SET_LOC(c, (stmt_ty)info->fb_datum); ADDOP(c, POP_BLOCK); if (preserve_tos) { @@ -1865,7 +1863,10 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP(c, YIELD_FROM); } ADDOP(c, POP_TOP); - c->u->u_lineno = loc; + /* The exit block should appear to execute after the + * statement causing the unwinding, so make the unwinding + * instruction artificial */ + c->u->u_lineno = -1; return 1; case HANDLER_CLEANUP: @@ -3020,12 +3021,17 @@ compiler_return(struct compiler *c, stmt_ty s) if (preserve_tos) { VISIT(c, expr, s->v.Return.value); } else { - /* Emit instruction with line number for expression */ + /* Emit instruction with line number for return value */ if (s->v.Return.value != NULL) { SET_LOC(c, s->v.Return.value); ADDOP(c, NOP); } } + if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) { + SET_LOC(c, s); + ADDOP(c, NOP); + } + if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) return 0; if (s->v.Return.value == NULL) { @@ -3044,6 +3050,8 @@ static int compiler_break(struct compiler *c) { struct fblockinfo *loop = NULL; + /* Emit instruction with line number */ + ADDOP(c, NOP); if (!compiler_unwind_fblock_stack(c, 0, &loop)) { return 0; } @@ -3062,6 +3070,8 @@ static int compiler_continue(struct compiler *c) { struct fblockinfo *loop = NULL; + /* Emit instruction with line number */ + ADDOP(c, NOP); if (!compiler_unwind_fblock_stack(c, 0, &loop)) { return 0; } @@ -4306,7 +4316,7 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) ADDOP_I(c, CALL_METHOD_KW, argsl + kwdsl); } else { - ADDOP_I(c, CALL_METHOD, argsl); + ADDOP_I(c, CALL_METHOD, argsl); } c->u->u_lineno = old_lineno; return 1; @@ -4473,7 +4483,7 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be return 1; } -/* Used by compiler_call_helper and maybe_optimize_method_call to emit +/* Used by compiler_call_helper and maybe_optimize_method_call to emit LOAD_CONST kw1 LOAD_CONST kw2 ... @@ -4484,7 +4494,7 @@ Returns 1 on success, 0 on error. */ static int compiler_call_simple_kw_helper(struct compiler *c, - asdl_keyword_seq *keywords, + asdl_keyword_seq *keywords, Py_ssize_t nkwelts) { PyObject *names; |