bpo-42645: Make sure that return/break/continue are only traced once when exiting via a finally block. (GH-23780)

* Make sure that return/break/continue are only traced once when exiting via a finally block.

* Add test for return in try-finally.

* Update importlib
This commit is contained in:
Mark Shannon 2020-12-16 13:07:01 +00:00 committed by GitHub
parent c71581c7a4
commit 5274b682bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 1791 additions and 1677 deletions

View file

@ -1695,19 +1695,22 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
return 1;
case FINALLY_TRY:
/* This POP_BLOCK gets the line number of the unwinding statement */
ADDOP(c, POP_BLOCK);
if (preserve_tos) {
if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) {
return 0;
}
}
/* Emit the finally block, restoring the line number when done */
int saved_lineno = c->u->u_lineno;
/* Emit the finally block */
VISIT_SEQ(c, stmt, info->fb_datum);
c->u->u_lineno = saved_lineno;
if (preserve_tos) {
compiler_pop_fblock(c, POP_VALUE, NULL);
}
/* The finally 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 FINALLY_END:
@ -2859,6 +2862,12 @@ 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 */
if (s->v.Return.value != NULL) {
SET_LOC(c, s->v.Return.value);
ADDOP(c, NOP);
}
}
if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL))
return 0;
@ -2866,7 +2875,7 @@ compiler_return(struct compiler *c, stmt_ty s)
ADDOP_LOAD_CONST(c, Py_None);
}
else if (!preserve_tos) {
VISIT(c, expr, s->v.Return.value);
ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value);
}
ADDOP(c, RETURN_VALUE);
NEXT_BLOCK(c);

3322
Python/importlib.h generated

File diff suppressed because it is too large Load diff