Repository navigation
error : use of undeclared identifier 'oparg' when building the tier 2 interpreter with tail calling #141967
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Nov 26, 2025 - addedinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)buildThe build process and cross-buildThe build process and cross-build
on Nov 26, 2025 I've just verified that I can still successfully build 3.14.0 using Visual Studio 2026 Community Edition which bundles clang 20.1.8 (if you select it in the installer)
build.bat --pgo --tail-call-interp "/p:PlatformToolset=ClangCL"build.bat -c Release --tail-call-interp "/p:PlatformToolset=ClangCL"build.bat -c Debug --tail-call-interp "/p:PlatformToolset=ClangCL"
which create x86_64 64bit tc binaries.
I've also just tested to build a 32bit binary
build.bat -p Win32 -c Debug --tail-call-interp "/p:PlatformToolset=ClangCL"
Also the current tip of the 3.14 branch (64d6bde) builds fine using
build.bat -c Release --tail-call-interp "/p:PlatformToolset=ClangCL"
and without tc
build.bat -c Release "/p:PlatformToolset=ClangCL"
I also did a lot of such builds during 3.14 development using VS 2022 and various different clang versions I have installed from https://github.com/llvm/llvm-project/releases and passing the additional
"/p:LLVMInstallDir=<my-clang-dir>"and"/p:LLVMToolsVersion=<my-clang-major-version>"parameters, e.g.build.bat --pgo "/p:PlatformToolset=ClangCL" "/p:LLVMInstallDir=C:\clang+llvm-20.1.6-x86_64-pc-windows-msvc" "/p:LLVMToolsVersion=20"
See more in section Building Python using Clang/LLVM in PCBuild/readme.txt.
Latest main builds for me as well, which I do on a regular basis.
How do you build? Do above commands work for you?
tail-call only works, combining with JIT fails (?), combining with JIT tier 2 fails with this issue.
Weirdly.... tail-call and JIT (additionally tier 2) are seemingly exclusive when I test. So we can't get full potential speed of tail calling and JIT interpreter.
Also happens on linux?
[winapiadmin@windows cpython]$ make clang -c -fno-strict-overflow -Wsign-compare -Wunreachable-code -DNDEBUG -g -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fvisibility=hidden -D_Py_TIER2=4 -I./Include/internal -I./Include/internal/mimalloc -I. -I./Include -DPy_BUILD_CORE -o Python/ceval.o Python/ceval.c In file included from Python/ceval.c:1094: Python/generated_cases.c.h:5584:13: error: use of undeclared identifier 'next_uop' 5584 | GOTO_TIER_TWO(executor); | ^~~~~~~~~~~~~~~~~~~~~~~ Python/ceval_macros.h:392:5: note: expanded from macro 'GOTO_TIER_TWO' 392 | next_uop = _executor->trace; \ | ^~~~~~~~ In file included from Python/ceval.c:1094: Python/generated_cases.c.h:5584:13: error: use of undeclared label 'enter_tier_two' Python/ceval_macros.h:394:10: note: expanded from macro 'GOTO_TIER_TWO' 394 | goto enter_tier_two; \ | ^ In file included from Python/ceval.c:1094: Python/generated_cases.c.h:7842:25: error: use of undeclared identifier 'next_uop' 7842 | GOTO_TIER_TWO(executor); | ^~~~~~~~~~~~~~~~~~~~~~~ Python/ceval_macros.h:392:5: note: expanded from macro 'GOTO_TIER_TWO' 392 | next_uop = _executor->trace; \ | ^~~~~~~~ In file included from Python/ceval.c:1094: Python/generated_cases.c.h:7842:25: error: use of undeclared label 'enter_tier_two' Python/ceval_macros.h:394:10: note: expanded from macro 'GOTO_TIER_TWO' 394 | goto enter_tier_two; \ | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:30:13: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 30 | oparg = CURRENT_OPARG(); | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:30:19: error: incompatible integer to pointer conversion assigning to 'char *' from 'const uint16_t' (aka 'const unsigned short') [-Wint-conversion] 30 | oparg = CURRENT_OPARG(); | ^ ~~~~~~~~~~~~~~~ Python/executor_cases.c.h:31:18: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 31 | if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:31:24: error: invalid operands to binary expression ('char *' and 'int') 31 | if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { | ~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~ Python/executor_cases.c.h:79:13: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 79 | oparg = CURRENT_OPARG(); | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:79:19: error: incompatible integer to pointer conversion assigning to 'char *' from 'const uint16_t' (aka 'const unsigned short') [-Wint-conversion] 79 | oparg = CURRENT_OPARG(); | ^ ~~~~~~~~~~~~~~~ Python/executor_cases.c.h:80:44: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 80 | _PyStackRef value_s = GETLOCAL(oparg); | ^~~~~ | optarg Python/ceval_macros.h:230:44: note: expanded from macro 'GETLOCAL' 230 | #define GETLOCAL(i) (frame->localsplus[i]) | ^ /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:80:35: error: array subscript is not an integer 80 | _PyStackRef value_s = GETLOCAL(oparg); | ^ ~~~~~ Python/ceval_macros.h:230:43: note: expanded from macro 'GETLOCAL' 230 | #define GETLOCAL(i) (frame->localsplus[i]) | ^~ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:85:82: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 85 | PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:85:82: error: incompatible pointer to integer conversion passing 'char *' to parameter of type 'Py_ssize_t' (aka 'long') [-Wint-conversion] 85 | PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) | ^~~~~ ./Include/tupleobject.h:32:62: note: passing argument to parameter here 32 | PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:99:13: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 99 | oparg = 0; | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:102:45: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 102 | value = PyStackRef_DUP(GETLOCAL(oparg)); | ^~~~~ | optarg Python/ceval_macros.h:230:44: note: expanded from macro 'GETLOCAL' 230 | #define GETLOCAL(i) (frame->localsplus[i]) | ^ /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:102:36: error: array subscript is not an integer 102 | value = PyStackRef_DUP(GETLOCAL(oparg)); | ^ ~~~~~ Python/ceval_macros.h:230:43: note: expanded from macro 'GETLOCAL' 230 | #define GETLOCAL(i) (frame->localsplus[i]) | ^~ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:111:13: error: use of undeclared identifier 'oparg'; did you mean 'optarg'? 111 | oparg = 1; | ^~~~~ | optarg /usr/include/bits/getopt_core.h:36:14: note: 'optarg' declared here 36 | extern char *optarg; | ^ In file included from Python/ceval.c:1291: Python/executor_cases.c.h:111:19: error: incompatible integer to pointer conversion assigning to 'char *' from 'int' [-Wint-conversion] 111 | oparg = 1; | ^ ~ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. make: *** [Makefile:3297: Python/ceval.o] Error 1Configure command:
./configure --with-tail-call-interp --enable-experimental-jit=interpreter CXX=clang++ CC=clangThis also fails with GCC. with more warnings.(JIT requires LLVM)tail-call only works, combining with JIT fails (?), combining with JIT tier 2 fails with this issue.
64d6bde (now only almost current tip of the 3.14 branch :) builds fine for me on Windows with tc and jit using
build.bat --experimental-jit --tail-call-interp "/p:PlatformToolset=ClangCL" "/p:LLVMInstallDir=<your-repo-root>\externals\llvm-19.1.7.0" "/p:LLVMToolsVersion=19"I highly recommend pinning clang to the same version as used for the jit stencils (
<your-repo-root>\externals\llvm-19.1.7.0in case of 3.14), because e.g."/p:LLVMInstallDir=<my-path-to>\llvm-21.1.4.0"smuggles its include path in front of the environment variable
INCLUDE=<my-path-to>\llvm-21.1.4.0\lib\clang\21\include;<other include paths>and then building of the jit stencils can fail (but that's totally different errors than those you mentioned above) 1.
Footnotes
-
I think the clang version used for building the stencils on Linux is not so tightly coupled to the one used to compile Python itself.
Furthermore, since https://github.com/python/cpython/issues/138497 it is possible to switch the clang version used for the stencil generation, but that's an environment variable used during configure which then sets a new command line option when invoking the generation of the stencils (--llvm-version=\"$LLVM_VERSION\"), so that's no help on Windows ... ↩
-
Weirdly.... tail-call and JIT (additionally tier 2) are seemingly exclusive when I test. So we can't get full potential speed of tail calling and JIT interpreter.
Ah, it seems you are using
--experimental-jit-interpreter, AKA "tier 2".
This one fails for me on 3.14 on Windows with the errors you've listed, too, but is working on latest main.Configure command:
./configure --with-tail-call-interp --enable-experimental-jit=interpreter CXX=clang++ CC=clangAh, again
--enable-experimental-jit=interpreter: you are not using the jit when specifying this, but rather the tier 2 interpreter,
which is mostly useful for debugging purposes (for JIT developers).See https://docs.python.org/dev/using/configure.html#cmdoption-enable-experimental-jit.
Latest main should work on Linux as well, @Fidget-Spinner did a lot of builds during his work on #139109 which at the beginning even mandated tail calling (since #141703 the tracing jit supports non-tc interpreters again).
- changed the title
[-]error : use of undeclared identifier 'oparg' on ClangCL[/-][+]error : use of undeclared identifier 'oparg' when building with --enable-experimental-jit=interpreter and --with-tail-call-interp[/+]on Nov 28, 2025 - changed the title
[-]error : use of undeclared identifier 'oparg' when building with --enable-experimental-jit=interpreter and --with-tail-call-interp[/-][+]error : use of undeclared identifier 'oparg' when building the tier 2 interpreter with tail calling[/+]on Nov 28, 2025 @winapiadmin tier 2 interpreter is for CPython internal testing only. It's not guaranteed to support the tail calling interpreter. Also, if you want to build JIT for speed, use
--enable-experimental-jit=yesnot--enable-experimental-jit=interpreter. That should work with tail calling.3.14 tier 2 interpreter was not working with tail calling, but 3.15 is. Again, it's only for CPython's testing, so I don't see a point in fixing it.
Reacted by Chris EiblA reminder that the tier 2 interpreter is like 10-20% slower at this point than the JIT. So you should benchmark first to ensure you actually see any speedups. I doubt you will see any speedup at all with the tier 2 interpreter.
Reacted by Chris Eibl
Bug report
Bug description:
(with tail call optimization, edit: + JIT tier 2)
But tail call optimization is supported on LLVM. I think this shouldn't be a duplicate of #141937
Related: #132132
(using both MSVC's clang-cl and LLVM 21.1.6 latest clang-cl)
CPython versions tested on:
3.14
Operating systems tested on:
Windows, Linux