Skip to content

Commit 1cc7e8f

Browse files
authored
[mypyc] Fix memory safety of list.count on free-threaded builds (#21680)
Work on mypyc/mypyc#1202.
1 parent 50e04b2 commit 1cc7e8f

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

mypyc/lib-rt/pythonsupport.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,33 @@ list_count(PyListObject *self, PyObject *value)
205205
Py_ssize_t count = 0;
206206
Py_ssize_t i;
207207

208+
#ifdef Py_GIL_DISABLED
209+
for (i = 0; i < PyList_GET_SIZE(self); i++) {
210+
PyObject *item = PyList_GetItemRef((PyObject *)self, i);
211+
if (unlikely(item == NULL)) {
212+
// Race condition: list shrank between size read and get item
213+
if (PyErr_ExceptionMatches(PyExc_IndexError)) {
214+
PyErr_Clear();
215+
break;
216+
}
217+
return CPY_INT_TAG;
218+
}
219+
int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
220+
Py_DECREF(item);
221+
if (cmp > 0)
222+
count++;
223+
else if (cmp < 0)
224+
return CPY_INT_TAG;
225+
}
226+
#else
208227
for (i = 0; i < Py_SIZE(self); i++) {
209228
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
210229
if (cmp > 0)
211230
count++;
212231
else if (cmp < 0)
213232
return CPY_INT_TAG;
214233
}
234+
#endif
215235
return CPyTagged_ShortFromSsize_t(count);
216236
}
217237

0 commit comments

Comments
 (0)