Skip to content

Commit e56f86f

Browse files
authored
gh-143493: fix cleanup on errors in codegen_comprehension (#156374)
1 parent 3a7a22b commit e56f86f

1 file changed

Lines changed: 47 additions & 33 deletions

File tree

Python/codegen.c

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5051,6 +5051,38 @@ pop_inlined_comprehension_state(compiler *c, location loc,
50515051
return SUCCESS;
50525052
}
50535053

5054+
static int
5055+
codegen_comprehension_init_container(compiler *c, location loc, int type,
5056+
int is_inlined, bool avoid_creation)
5057+
{
5058+
int op;
5059+
switch (type) {
5060+
case COMP_LISTCOMP:
5061+
op = BUILD_LIST;
5062+
break;
5063+
case COMP_SETCOMP:
5064+
op = BUILD_SET;
5065+
break;
5066+
case COMP_DICTCOMP:
5067+
op = BUILD_MAP;
5068+
break;
5069+
default:
5070+
PyErr_Format(PyExc_SystemError,
5071+
"unknown comprehension type %d", type);
5072+
return ERROR;
5073+
}
5074+
5075+
if (!avoid_creation) {
5076+
ADDOP_I(c, loc, op, 0);
5077+
if (is_inlined) {
5078+
ADDOP_I(c, loc, SWAP, 2);
5079+
}
5080+
} else {
5081+
ADDOP_I(c, loc, COPY, 1);
5082+
}
5083+
return SUCCESS;
5084+
}
5085+
50545086
static int
50555087
codegen_comprehension(compiler *c, expr_ty e, int type,
50565088
identifier name, asdl_comprehension_seq *generators, expr_ty elt,
@@ -5089,19 +5121,22 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50895121
if (type == COMP_GENEXP) {
50905122
/* Insert GET_ITER before RETURN_GENERATOR.
50915123
https://docs.python.org/3/reference/expressions.html#generator-expressions */
5092-
RETURN_IF_ERROR(
5093-
_PyInstructionSequence_InsertInstruction(
5124+
if(_PyInstructionSequence_InsertInstruction(
50945125
INSTR_SEQUENCE(c), 0,
5095-
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION));
5096-
RETURN_IF_ERROR(
5097-
_PyInstructionSequence_InsertInstruction(
5126+
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION) < 0) {
5127+
goto error_in_scope;
5128+
}
5129+
if(_PyInstructionSequence_InsertInstruction(
50985130
INSTR_SEQUENCE(c), 1,
5099-
LOAD_FAST, 0, LOC(outermost->iter)));
5100-
RETURN_IF_ERROR(
5101-
_PyInstructionSequence_InsertInstruction(
5131+
LOAD_FAST, 0, LOC(outermost->iter)) < 0) {
5132+
goto error_in_scope;
5133+
}
5134+
if(_PyInstructionSequence_InsertInstruction(
51025135
INSTR_SEQUENCE(c), 2,
51035136
outermost->is_async ? GET_AITER : GET_ITER,
5104-
0, LOC(outermost->iter)));
5137+
0, LOC(outermost->iter)) < 0) {
5138+
goto error_in_scope;
5139+
}
51055140
iter_state = ITERATOR_ON_STACK;
51065141
}
51075142
else {
@@ -5111,31 +5146,10 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
51115146
Py_CLEAR(entry);
51125147

51135148
if (type != COMP_GENEXP) {
5114-
int op;
5115-
switch (type) {
5116-
case COMP_LISTCOMP:
5117-
op = BUILD_LIST;
5118-
break;
5119-
case COMP_SETCOMP:
5120-
op = BUILD_SET;
5121-
break;
5122-
case COMP_DICTCOMP:
5123-
op = BUILD_MAP;
5124-
break;
5125-
default:
5126-
PyErr_Format(PyExc_SystemError,
5127-
"unknown comprehension type %d", type);
5149+
if (codegen_comprehension_init_container(
5150+
c, loc, type, is_inlined, avoid_creation) < 0) {
51285151
goto error_in_scope;
51295152
}
5130-
5131-
if (!avoid_creation) {
5132-
ADDOP_I(c, loc, op, 0);
5133-
if (is_inlined) {
5134-
ADDOP_I(c, loc, SWAP, 2);
5135-
}
5136-
} else {
5137-
ADDOP_I(c, loc, COPY, 1);
5138-
}
51395153
}
51405154
if (codegen_comprehension_generator(c, loc, generators, 0, 0,
51415155
elt, val, type, iter_state, avoid_creation) < 0) {
@@ -5150,7 +5164,7 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
51505164
}
51515165

51525166
if (type != COMP_GENEXP) {
5153-
ADDOP(c, LOC(e), RETURN_VALUE);
5167+
ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
51545168
}
51555169
if (type == COMP_GENEXP) {
51565170
if (codegen_wrap_in_stopiteration_handler(c) < 0) {

0 commit comments

Comments
 (0)