Skip to content

Commit 683ef40

Browse files
authored
gh-156466: fix cleanup on error in codegen_class_body (#156507)
1 parent 932822c commit 683ef40

1 file changed

Lines changed: 24 additions & 26 deletions

File tree

Python/codegen.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -310,19 +310,23 @@ codegen_addop_load_const(compiler *c, location loc, PyObject *o)
310310
#define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
311311
RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const((C), (LOC), (O)))
312312

313+
static int
314+
codegen_addop_load_const_new(compiler *c, location loc, PyObject *o)
315+
{
316+
if (o == NULL) {
317+
return ERROR;
318+
}
319+
int ret = codegen_addop_load_const(c, loc, o);
320+
Py_DECREF(o);
321+
return ret;
322+
}
323+
313324
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
314-
#define ADDOP_LOAD_CONST_NEW(C, LOC, O) \
315-
do { \
316-
PyObject *__new_const = (O); \
317-
if (__new_const == NULL) { \
318-
return ERROR; \
319-
} \
320-
if (codegen_addop_load_const((C), (LOC), __new_const) < 0) { \
321-
Py_DECREF(__new_const); \
322-
return ERROR; \
323-
} \
324-
Py_DECREF(__new_const); \
325-
} while (0)
325+
#define ADDOP_LOAD_CONST_NEW(C, LOC, O) \
326+
RETURN_IF_ERROR(codegen_addop_load_const_new((C), (LOC), (O)))
327+
328+
#define ADDOP_LOAD_CONST_NEW_IN_SCOPE(C, LOC, O) \
329+
RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const_new((C), (LOC), (O)))
326330

327331
static int
328332
codegen_addop_o(compiler *c, location loc,
@@ -1613,16 +1617,16 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
16131617
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
16141618
/* ... and store it as __module__ */
16151619
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1616-
ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1620+
ADDOP_LOAD_CONST_IN_SCOPE(c, loc, QUALNAME(c));
16171621
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1618-
ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1622+
ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
16191623
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
16201624
asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
16211625
if (asdl_seq_LEN(type_params) > 0) {
16221626
RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
16231627
}
16241628
if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1625-
ADDOP(c, loc, LOAD_LOCALS);
1629+
ADDOP_IN_SCOPE(c, loc, LOAD_LOCALS);
16261630

16271631
// We can't use codegen_nameop here because we need to generate a
16281632
// STORE_DEREF in a class namespace, and codegen_nameop() won't do
@@ -1635,13 +1639,7 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
16351639
}
16361640
/* compile the body proper */
16371641
RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1638-
PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1639-
if (static_attributes == NULL) {
1640-
_PyCompile_ExitScope(c);
1641-
return ERROR;
1642-
}
1643-
ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1644-
Py_CLEAR(static_attributes);
1642+
ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, NO_LOCATION, _PyCompile_StaticAttributesAsTuple(c));
16451643
RETURN_IF_ERROR_IN_SCOPE(
16461644
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
16471645
/* The following code is artificial */
@@ -1650,7 +1648,7 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
16501648
/* Store __classdictcell__ into class namespace */
16511649
int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
16521650
RETURN_IF_ERROR_IN_SCOPE(c, i);
1653-
ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1651+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
16541652
RETURN_IF_ERROR_IN_SCOPE(
16551653
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
16561654
}
@@ -1659,14 +1657,14 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
16591657
/* Store __classcell__ into class namespace & return it */
16601658
int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
16611659
RETURN_IF_ERROR_IN_SCOPE(c, i);
1662-
ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1663-
ADDOP_I(c, NO_LOCATION, COPY, 1);
1660+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
1661+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, COPY, 1);
16641662
RETURN_IF_ERROR_IN_SCOPE(
16651663
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
16661664
}
16671665
else {
16681666
/* No methods referenced __class__, so just return None */
1669-
ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1667+
ADDOP_LOAD_CONST_IN_SCOPE(c, NO_LOCATION, Py_None);
16701668
}
16711669
ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
16721670
/* create the code object */

0 commit comments

Comments
 (0)