python / python/cpython

_Py_ThreadId() fails to compile with clang on Windows ARM64 (MSYS2 CLANGARM64)

Ouverte
#157,212 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

build OS-windows topic-free-threading type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

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.h declares unsigned __int64 __getReg(int);, but only inside #ifdef _MSC_VER. For a *-windows-gnu target the header takes the #include_next <intrin.h> path and defers to mingw-w64.
  • mingw-w64's intrin.h declares __getReg only via __MACHINEIA64 (Itanium), which expands to nothing unless __ia64__. There is no __MACHINEARM64 entry 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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par les branches de plateforme de _Py_ThreadId() dans Include/object.h et reproduisez l’échec à l’aide de l’exemple repro.c et de la commande du compilateur fournis. Consultez les PR liés gh-157252 et gh-157253 pour prendre connaissance du travail déjà en cours. La tâche est terminée lorsque la reproduction free-threaded Windows ARM64 CLANGARM64 se compile et lit correctement un identifiant par thread.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
c, python
Domaine
build-system, operating-systems
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
30/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.