Skip to content

Commit 28b944c

Browse files
[3.14] gh-156466: fix cleanup on error in codegen_class_body (GH-156507) (#156536)
gh-156466: fix cleanup on error in codegen_class_body (GH-156507) (cherry picked from commit 683ef40) Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
1 parent 0267ee6 commit 28b944c

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
@@ -303,19 +303,23 @@ codegen_addop_load_const(compiler *c, location loc, PyObject *o)
303303
#define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
304304
RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const((C), (LOC), (O)))
305305

306+
static int
307+
codegen_addop_load_const_new(compiler *c, location loc, PyObject *o)
308+
{
309+
if (o == NULL) {
310+
return ERROR;
311+
}
312+
int ret = codegen_addop_load_const(c, loc, o);
313+
Py_DECREF(o);
314+
return ret;
315+
}
316+
306317
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
307-
#define ADDOP_LOAD_CONST_NEW(C, LOC, O) \
308-
do { \
309-
PyObject *__new_const = (O); \
310-
if (__new_const == NULL) { \
311-
return ERROR; \
312-
} \
313-
if (codegen_addop_load_const((C), (LOC), __new_const) < 0) { \
314-
Py_DECREF(__new_const); \
315-
return ERROR; \
316-
} \
317-
Py_DECREF(__new_const); \
318-
} while (0)
318+
#define ADDOP_LOAD_CONST_NEW(C, LOC, O) \
319+
RETURN_IF_ERROR(codegen_addop_load_const_new((C), (LOC), (O)))
320+
321+
#define ADDOP_LOAD_CONST_NEW_IN_SCOPE(C, LOC, O) \
322+
RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const_new((C), (LOC), (O)))
319323

320324
static int
321325
codegen_addop_o(compiler *c, location loc,
@@ -1542,16 +1546,16 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
15421546
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
15431547
/* ... and store it as __module__ */
15441548
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1545-
ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1549+
ADDOP_LOAD_CONST_IN_SCOPE(c, loc, QUALNAME(c));
15461550
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1547-
ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1551+
ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
15481552
RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
15491553
asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
15501554
if (asdl_seq_LEN(type_params) > 0) {
15511555
RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
15521556
}
15531557
if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1554-
ADDOP(c, loc, LOAD_LOCALS);
1558+
ADDOP_IN_SCOPE(c, loc, LOAD_LOCALS);
15551559

15561560
// We can't use codegen_nameop here because we need to generate a
15571561
// STORE_DEREF in a class namespace, and codegen_nameop() won't do
@@ -1564,13 +1568,7 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
15641568
}
15651569
/* compile the body proper */
15661570
RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1567-
PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1568-
if (static_attributes == NULL) {
1569-
_PyCompile_ExitScope(c);
1570-
return ERROR;
1571-
}
1572-
ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1573-
Py_CLEAR(static_attributes);
1571+
ADDOP_LOAD_CONST_NEW_IN_SCOPE(c, NO_LOCATION, _PyCompile_StaticAttributesAsTuple(c));
15741572
RETURN_IF_ERROR_IN_SCOPE(
15751573
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
15761574
/* The following code is artificial */
@@ -1579,7 +1577,7 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
15791577
/* Store __classdictcell__ into class namespace */
15801578
int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
15811579
RETURN_IF_ERROR_IN_SCOPE(c, i);
1582-
ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1580+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
15831581
RETURN_IF_ERROR_IN_SCOPE(
15841582
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
15851583
}
@@ -1588,14 +1586,14 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
15881586
/* Store __classcell__ into class namespace & return it */
15891587
int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
15901588
RETURN_IF_ERROR_IN_SCOPE(c, i);
1591-
ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1592-
ADDOP_I(c, NO_LOCATION, COPY, 1);
1589+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, LOAD_CLOSURE, i);
1590+
ADDOP_I_IN_SCOPE(c, NO_LOCATION, COPY, 1);
15931591
RETURN_IF_ERROR_IN_SCOPE(
15941592
c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
15951593
}
15961594
else {
15971595
/* No methods referenced __class__, so just return None */
1598-
ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1596+
ADDOP_LOAD_CONST_IN_SCOPE(c, NO_LOCATION, Py_None);
15991597
}
16001598
ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
16011599
/* create the code object */

0 commit comments

Comments
 (0)