diff options
author | Mark Shannon <mark@hotpy.org> | 2020-09-25 13:04:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-25 13:04:19 (GMT) |
commit | 02d126aa09d96d03dcf9c5b51c858ce5ef386601 (patch) | |
tree | 85817061b2ed79451edc432495040fc279067e7d /Python/compile.c | |
parent | 05cc881cbcf5d73a312568c78c7149eae3195072 (diff) | |
download | cpython-02d126aa09d96d03dcf9c5b51c858ce5ef386601.zip cpython-02d126aa09d96d03dcf9c5b51c858ce5ef386601.tar.gz cpython-02d126aa09d96d03dcf9c5b51c858ce5ef386601.tar.bz2 |
bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395)
* Account for control blocks in 'except' in compiler. Fixes #39934.
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/Python/compile.c b/Python/compile.c index 0f9e5c2..f2563d7 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -108,8 +108,8 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE }; +enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER }; struct fblockinfo { enum fblocktype fb_type; @@ -1623,9 +1623,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - PyErr_SetString(PyExc_SyntaxError, - "too many statically nested blocks"); - return 0; + return compiler_error(c, "too many statically nested blocks"); } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; @@ -1665,6 +1663,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, { switch (info->fb_type) { case WHILE_LOOP: + case EXCEPTION_HANDLER: return 1; case FOR_LOOP: @@ -1675,7 +1674,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP(c, POP_TOP); return 1; - case EXCEPT: + case TRY_EXCEPT: ADDOP(c, POP_BLOCK); return 1; @@ -3060,14 +3059,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) return 0; ADDOP_JUMP(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) + if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, EXCEPT, body); + compiler_pop_fblock(c, TRY_EXCEPT, body); ADDOP_JUMP(c, JUMP_FORWARD, orelse); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); + /* Runtime will push a block here, so we need to account for that */ + if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) + return 0; for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); @@ -3152,6 +3154,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) } compiler_use_next_block(c, except); } + compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); ADDOP(c, RERAISE); compiler_use_next_block(c, orelse); VISIT_SEQ(c, stmt, s->v.Try.orelse); |