Skip to content

Commit a8c0c60

Browse files
committed
refactor codegen_deferred_annotations_body to ensure mangled is decref'd on error
1 parent 617f4cc commit a8c0c60

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

Python/codegen.c

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,41 @@ codegen_leave_annotations_scope(compiler *c, location loc)
777777
return SUCCESS;
778778
}
779779

780+
static int
781+
codegen_deferred_annotations_entry(compiler *c, location loc,
782+
PyObject *conditional_annotation_indices, int scope_type, stmt_ty st, PyObject *mangled, Py_ssize_t i)
783+
{
784+
PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
785+
assert(PyLong_CheckExact(cond_index));
786+
long idx = PyLong_AS_LONG(cond_index);
787+
NEW_JUMP_TARGET_LABEL(c, not_set);
788+
789+
if (idx != -1) {
790+
ADDOP_LOAD_CONST(c, LOC(st), cond_index);
791+
if (scope_type == COMPILE_SCOPE_CLASS) {
792+
ADDOP_NAME(
793+
c, LOC(st), LOAD_DEREF, &_Py_ID(__conditional_annotations__), freevars);
794+
}
795+
else {
796+
ADDOP_NAME(
797+
c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
798+
}
799+
800+
ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
801+
ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
802+
}
803+
804+
VISIT(c, expr, st->v.AnnAssign.annotation);
805+
ADDOP_I(c, LOC(st), COPY, 2);
806+
ADDOP_LOAD_CONST(c, LOC(st), mangled);
807+
// stack now contains <annos> <name> <annos> <value>
808+
ADDOP(c, loc, STORE_SUBSCR);
809+
// stack now contains <annos>
810+
811+
USE_LABEL(c, not_set);
812+
return SUCCESS;
813+
}
814+
780815
static int
781816
codegen_deferred_annotations_body(compiler *c, location loc,
782817
PyObject *deferred_anno, PyObject *conditional_annotation_indices, int scope_type)
@@ -798,37 +833,11 @@ codegen_deferred_annotations_body(compiler *c, location loc,
798833
if (!mangled) {
799834
return ERROR;
800835
}
801-
// NOTE: ref of mangled can be leaked on ADDOP* and VISIT macros due to early returns
802-
// fixing would require an overhaul of these macros
803-
804-
PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
805-
assert(PyLong_CheckExact(cond_index));
806-
long idx = PyLong_AS_LONG(cond_index);
807-
NEW_JUMP_TARGET_LABEL(c, not_set);
808-
809-
if (idx != -1) {
810-
ADDOP_LOAD_CONST(c, LOC(st), cond_index);
811-
if (scope_type == COMPILE_SCOPE_CLASS) {
812-
ADDOP_NAME(
813-
c, LOC(st), LOAD_DEREF, &_Py_ID(__conditional_annotations__), freevars);
814-
}
815-
else {
816-
ADDOP_NAME(
817-
c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
818-
}
819836

820-
ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
821-
ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
822-
}
823-
824-
VISIT(c, expr, st->v.AnnAssign.annotation);
825-
ADDOP_I(c, LOC(st), COPY, 2);
826-
ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
827-
// stack now contains <annos> <name> <annos> <value>
828-
ADDOP(c, loc, STORE_SUBSCR);
829-
// stack now contains <annos>
830-
831-
USE_LABEL(c, not_set);
837+
int ret = codegen_deferred_annotations_entry(c, loc, conditional_annotation_indices,
838+
scope_type, st, mangled, i);
839+
Py_DECREF(mangled);
840+
RETURN_IF_ERROR(ret);
832841
}
833842
return SUCCESS;
834843
}

0 commit comments

Comments
 (0)