_Py_ThreadId() fails to compile with clang on Windows ARM64 (MSYS2 CLANGARM64)
還沒有人認領這個 Issue。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
Building a free-threaded extension module for Windows ARM64 with MSYS2's CLANGARM64 (llvm-mingw) toolchain fails to compile Include/object.h:
object.h:200:11: error: call to undeclared function '__getReg'; ISO C99 and later do not
support implicit function declarations [-Wimplicit-function-declaration]
200 | tid = __getReg(18);
| ^
Example actions run where I tried to build jq.py.
Minimal repro
/* repro.c */
#include <Python.h>
uintptr_t repro(void) { return _Py_ThreadId(); }
$ gcc -c repro.c -O1 -Wall -DPy_GIL_DISABLED=1 -I <freethreaded-arm64-headers>
In file included from repro.c:1:
In file included from Python.h:81:
object.h:200:11: error: call to undeclared function '__getReg'; ISO C99 and later do not
support implicit function declarations [-Wimplicit-function-declaration]
200 | tid = __getReg(18);
| ^
1 error generated.
(gcc here is mingw-w64-clang-aarch64-gcc-compat, i.e. clang.)
_Py_ThreadId() reaches this branch, added in #124609 / GH-124663 for GCC:
#elif defined(__MINGW32__) && defined(_M_ARM64)
tid = __getReg(18);
clang does not define _M_ARM64 but mingw-w64 does, in _mingw_mac.h:
#if defined(__aarch64__) && !defined(_M_ARM64)
# define _M_ARM64 1
which is pulled in transitively by pyconfig.h. So the condition is true all aarch64 compilers. clang's predefines here are:
#define _WIN32 1
#define __GNUC__ 4
#define __MINGW32__ 1
#define __MINGW64__ 1
#define __aarch64__ 1
#define __clang__ 1
Why __getReg is unavailable to clang
- clang's
intrin.hdeclaresunsigned __int64 __getReg(int);, but only inside#ifdef _MSC_VER. For a*-windows-gnutarget the header takes the#include_next <intrin.h>path and defers to mingw-w64. - mingw-w64's
intrin.hdeclares__getRegonly via__MACHINEIA64(Itanium), which expands to nothing unless__ia64__. There is no__MACHINEARM64entry for it. - It is also not a clang builtin.
Note that falling through to the __aarch64__ branch is not a valid fix:
#elif defined(__aarch64__)
__asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
On Windows ARM64 tpidr_el0 reads as 0 on every thread, whereas x18 holds the TEB and is correctly per-thread:
main x18=000000cc3736d000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc3736d000
thr1 x18=000000cc37371000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc37371000
thr2 x18=000000cc37373000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc37373000
A constant 0 would collide with _Py_UNOWNED_TID, so this would compile cleanly and then misbehave silently — the same failure mode discussed in #124609.
Suggested fix
Keep __getReg for GCC and give clang a dedicated branch reading x18:
#elif defined(__MINGW32__) && defined(_M_ARM64) && !defined(__clang__)
tid = __getReg(18);
#elif defined(__MINGW32__) && defined(_M_ARM64)
__asm__ ("mov %0, x18" : "=r" (tid)); // Windows/ARM64 keeps the TEB in x18
I have verified that this compiles and generates the expected read.
Versions tested
- CPython 3.14 (free-threaded)
- Windows 11 Pro 10.0.28000 ARM64
- clang 22.1.8 (MSYS2 CLANGARM64)
CPython versions tested on:
3.14
Operating systems tested on:
Windows
Linked PRs
- gh-157252
- gh-157253
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 Include/object.h 中的 _Py_ThreadId() 平台分支開始,使用提供的 repro.c 範例和編譯器命令重現該失敗。查看連結的 PR gh-157252 和 gh-157253,了解已在進行的工作。當 free-threaded Windows ARM64 CLANGARM64 的重現程式碼能夠編譯並正確讀取每執行緒識別碼時,即表示完成。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- c, python
- 領域
- build-system, operating-systems
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 停滯
- 描述清晰度
- 描述清楚
- 新手友好度
- 30/100