]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-148284: Block inlining of gigantic functions in ceval.c for clang 22 (GH-148334)
authorKen Jin <kenjin@python.org>
Fri, 10 Apr 2026 16:52:23 +0000 (00:52 +0800)
committerGitHub <noreply@github.com>
Fri, 10 Apr 2026 16:52:23 +0000 (00:52 +0800)
Co-authored-by: Victor Stinner <vstinner@python.org>
Doc/using/configure.rst
Makefile.pre.in
Misc/NEWS.d/next/Core_and_Builtins/2026-04-10-14-20-54.gh-issue-148284.HKs-S_.rst [new file with mode: 0644]
configure
configure.ac

index 82409ac0cdcfa6e85479ebdc6e81c4a3b339f456..bf25de7cc90c6c081f9ee6b5f32d8add2dadb870 100644 (file)
@@ -1574,6 +1574,12 @@ Compiler flags
 
    .. versionadded:: 3.7
 
+.. envvar:: CFLAGS_CEVAL
+
+   Flags used to compile ``Python/ceval.c``.
+
+   .. versionadded:: 3.14.5
+
 .. envvar:: CCSHARED
 
    Compiler flags used to build a shared library.
index 354580aa482d253d533fa1c9ad2333853aa0f09c..8d325a4932509d2c48decd0b01b518316121322d 100644 (file)
@@ -130,6 +130,8 @@ CONFIGURE_EXE_LDFLAGS=@EXE_LDFLAGS@
 PY_CORE_EXE_LDFLAGS:= $(if $(CONFIGURE_EXE_LDFLAGS), $(CONFIGURE_EXE_LDFLAGS) $(PY_LDFLAGS_NODIST), $(PY_CORE_LDFLAGS))
 # Strict or non-strict aliasing flags used to compile dtoa.c, see above
 CFLAGS_ALIASING=@CFLAGS_ALIASING@
+# Compilation flags only for ceval.c.
+CFLAGS_CEVAL=@CFLAGS_CEVAL@
 
 
 # Machine-dependent subdirectories
@@ -3203,6 +3205,9 @@ regen-jit:
 Python/dtoa.o: Python/dtoa.c
        $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $<
 
+Python/ceval.o: Python/ceval.c
+       $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_CEVAL) -o $@ $<
+
 # Run reindent on the library
 .PHONY: reindent
 reindent:
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-10-14-20-54.gh-issue-148284.HKs-S_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-10-14-20-54.gh-issue-148284.HKs-S_.rst
new file mode 100644 (file)
index 0000000..a74f6c1
--- /dev/null
@@ -0,0 +1 @@
+Fix high stack consumption in Python's interpreter loop on Clang 22 by setting function limits for inlining when building with computed gotos.
index 4726b4fe3102ace9a0d21b54206ca7509227c809..a599cd639eac6fdc66f516c344aa060b1ed760a8 100755 (executable)
--- a/configure
+++ b/configure
@@ -829,6 +829,7 @@ OPENSSL_LDFLAGS
 OPENSSL_LIBS
 OPENSSL_INCLUDES
 ENSUREPIP
+CFLAGS_CEVAL
 SRCDIRS
 THREADHEADERS
 PANEL_LIBS
@@ -30358,6 +30359,52 @@ printf "%s\n" "#define HAVE_GLIBC_MEMMOVE_BUG 1" >>confdefs.h
 
 fi
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we need to manually block large inlining in ceval.c" >&5
+printf %s "checking if we need to manually block large inlining in ceval.c... " >&6; }
+if test "$cross_compiling" = yes
+then :
+  block_huge_inlining_in_ceval=undefined
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int main(void) {
+// See gh-148284: Clang 22 seems to have interactions with inlining
+// and the stackref buffer which cause 40 kB of stack usage on x86-64
+// in buggy versions of _PyEval_EvalFrameDefault() in computed goto
+// interpreter. The normal usage seen is normally 1-2 kB.
+#if defined(__clang__) && (__clang_major__ == 22)
+    return 1;
+#else
+    return 0;
+#endif
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  block_huge_inlining_in_ceval=no
+else case e in #(
+  e) block_huge_inlining_in_ceval=yes ;;
+esac
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $block_huge_inlining_in_ceval" >&5
+printf "%s\n" "$block_huge_inlining_in_ceval" >&6; }
+
+if test "$block_huge_inlining_in_ceval" = yes && test "$ac_cv_computed_gotos" = yes; then
+    # gh-148284: Suppress inlining of functions whose stack size exceeds
+    # 512 bytes. This number should be tuned to follow the C stack
+    # consumption in _PyEval_EvalFrameDefault() on computed goto
+    # interpreter.
+    CFLAGS_CEVAL="$CFLAGS_CEVAL -finline-max-stacksize=512"
+fi
+
+
 if test "$ac_cv_gcc_asm_for_x87" = yes; then
     # Some versions of gcc miscompile inline asm:
     # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491
index dd860292cc20587d35bca556e882a4b56cc35320..d7785c6f3e6e73aae674f18e7c406b39a5c6e463 100644 (file)
@@ -7371,6 +7371,34 @@ if test "$have_glibc_memmove_bug" = yes; then
      for memmove and bcopy.])
 fi
 
+AC_MSG_CHECKING([if we need to manually block large inlining in ceval.c])
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+int main(void) {
+// See gh-148284: Clang 22 seems to have interactions with inlining
+// and the stackref buffer which cause 40 kB of stack usage on x86-64
+// in buggy versions of _PyEval_EvalFrameDefault() in computed goto
+// interpreter. The normal usage seen is normally 1-2 kB.
+#if defined(__clang__) && (__clang_major__ == 22)
+    return 1;
+#else
+    return 0;
+#endif
+}
+]])],
+[block_huge_inlining_in_ceval=no],
+[block_huge_inlining_in_ceval=yes],
+[block_huge_inlining_in_ceval=undefined])
+AC_MSG_RESULT([$block_huge_inlining_in_ceval])
+
+if test "$block_huge_inlining_in_ceval" = yes && test "$ac_cv_computed_gotos" = yes; then
+    # gh-148284: Suppress inlining of functions whose stack size exceeds
+    # 512 bytes. This number should be tuned to follow the C stack
+    # consumption in _PyEval_EvalFrameDefault() on computed goto
+    # interpreter.
+    CFLAGS_CEVAL="$CFLAGS_CEVAL -finline-max-stacksize=512"
+fi
+AC_SUBST([CFLAGS_CEVAL])
+
 if test "$ac_cv_gcc_asm_for_x87" = yes; then
     # Some versions of gcc miscompile inline asm:
     # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491