From 57f45ee2d8ee23c2a1d1daba4095a5a044169419 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 12 Feb 2025 09:34:40 -0500 Subject: gh-128759: Fix accesses to `tp_version_tag`. (GH-129750) We should use a relaxed atomic load in the free threading build in `PyType_Modified()` because that's called without the type lock held. It's not necessary to use atomics in `type_modified_unlocked()`. We should also use `FT_ATOMIC_STORE_UINT_RELAXED()` instead of the `UINT32` variant because `tp_version_tag` is declared as `unsigned int`. --- Objects/typeobject.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 59ea2e3..1484d9b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1010,7 +1010,7 @@ set_version_unlocked(PyTypeObject *tp, unsigned int version) _Py_atomic_add_uint16(&tp->tp_versions_used, 1); } #endif - FT_ATOMIC_STORE_UINT32_RELAXED(tp->tp_version_tag, version); + FT_ATOMIC_STORE_UINT_RELAXED(tp->tp_version_tag, version); #ifndef Py_GIL_DISABLED if (version != 0) { PyTypeObject **slot = @@ -1039,7 +1039,8 @@ type_modified_unlocked(PyTypeObject *type) We don't assign new version tags eagerly, but only as needed. */ - if (FT_ATOMIC_LOAD_UINT_RELAXED(type->tp_version_tag) == 0) { + ASSERT_TYPE_LOCK_HELD(); + if (type->tp_version_tag == 0) { return; } // Cannot modify static builtin types. @@ -1094,7 +1095,7 @@ void PyType_Modified(PyTypeObject *type) { // Quick check without the lock held - if (type->tp_version_tag == 0) { + if (FT_ATOMIC_LOAD_UINT_RELAXED(type->tp_version_tag) == 0) { return; } -- cgit v0.12