Skip to content

Commit 8870e26

Browse files
authored
[3.15] gh-143493: fix cleanup on errors in codegen_comprehension (GH-156374) (GH-156962)
1 parent 0bc9a39 commit 8870e26

1 file changed

Lines changed: 42 additions & 29 deletions

File tree

‎Python/codegen.c‎

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4967,6 +4967,34 @@ pop_inlined_comprehension_state(compiler *c, location loc,
49674967
return SUCCESS;
49684968
}
49694969

4970+
static int
4971+
codegen_comprehension_init_container(compiler *c, location loc, int type,
4972+
int is_inlined)
4973+
{
4974+
int op;
4975+
switch (type) {
4976+
case COMP_LISTCOMP:
4977+
op = BUILD_LIST;
4978+
break;
4979+
case COMP_SETCOMP:
4980+
op = BUILD_SET;
4981+
break;
4982+
case COMP_DICTCOMP:
4983+
op = BUILD_MAP;
4984+
break;
4985+
default:
4986+
PyErr_Format(PyExc_SystemError,
4987+
"unknown comprehension type %d", type);
4988+
return ERROR;
4989+
}
4990+
4991+
ADDOP_I(c, loc, op, 0);
4992+
if (is_inlined) {
4993+
ADDOP_I(c, loc, SWAP, 2);
4994+
}
4995+
return SUCCESS;
4996+
}
4997+
49704998
static int
49714999
codegen_comprehension(compiler *c, expr_ty e, int type,
49725000
identifier name, asdl_comprehension_seq *generators, expr_ty elt,
@@ -5005,19 +5033,22 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50055033
if (type == COMP_GENEXP) {
50065034
/* Insert GET_ITER before RETURN_GENERATOR.
50075035
https://docs.python.org/3/reference/expressions.html#generator-expressions */
5008-
RETURN_IF_ERROR(
5009-
_PyInstructionSequence_InsertInstruction(
5036+
if (_PyInstructionSequence_InsertInstruction(
50105037
INSTR_SEQUENCE(c), 0,
5011-
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION));
5012-
RETURN_IF_ERROR(
5013-
_PyInstructionSequence_InsertInstruction(
5038+
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION) < 0) {
5039+
goto error_in_scope;
5040+
}
5041+
if (_PyInstructionSequence_InsertInstruction(
50145042
INSTR_SEQUENCE(c), 1,
5015-
LOAD_FAST, 0, LOC(outermost->iter)));
5016-
RETURN_IF_ERROR(
5017-
_PyInstructionSequence_InsertInstruction(
5043+
LOAD_FAST, 0, LOC(outermost->iter)) < 0) {
5044+
goto error_in_scope;
5045+
}
5046+
if (_PyInstructionSequence_InsertInstruction(
50185047
INSTR_SEQUENCE(c), 2,
50195048
outermost->is_async ? GET_AITER : GET_ITER,
5020-
0, LOC(outermost->iter)));
5049+
0, LOC(outermost->iter)) < 0) {
5050+
goto error_in_scope;
5051+
}
50215052
iter_state = ITERATOR_ON_STACK;
50225053
}
50235054
else {
@@ -5027,27 +5058,9 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50275058
Py_CLEAR(entry);
50285059

50295060
if (type != COMP_GENEXP) {
5030-
int op;
5031-
switch (type) {
5032-
case COMP_LISTCOMP:
5033-
op = BUILD_LIST;
5034-
break;
5035-
case COMP_SETCOMP:
5036-
op = BUILD_SET;
5037-
break;
5038-
case COMP_DICTCOMP:
5039-
op = BUILD_MAP;
5040-
break;
5041-
default:
5042-
PyErr_Format(PyExc_SystemError,
5043-
"unknown comprehension type %d", type);
5061+
if (codegen_comprehension_init_container(c, loc, type, is_inlined) < 0) {
50445062
goto error_in_scope;
50455063
}
5046-
5047-
ADDOP_I(c, loc, op, 0);
5048-
if (is_inlined) {
5049-
ADDOP_I(c, loc, SWAP, 2);
5050-
}
50515064
}
50525065
if (codegen_comprehension_generator(c, loc, generators, 0, 0,
50535066
elt, val, type, iter_state) < 0) {
@@ -5062,7 +5075,7 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50625075
}
50635076

50645077
if (type != COMP_GENEXP) {
5065-
ADDOP(c, LOC(e), RETURN_VALUE);
5078+
ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
50665079
}
50675080
if (type == COMP_GENEXP) {
50685081
if (codegen_wrap_in_stopiteration_handler(c) < 0) {

0 commit comments

Comments
 (0)