From 85e5cbd5ca94c4ad211628b2a6ef19493ceaee76 Mon Sep 17 00:00:00 2001 From: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Date: Fri, 12 Jul 2024 21:13:03 +0800 Subject: [PATCH] gh-121647: Define _Py_TYPEOF macro on more compilers Extend the _Py_TYPEOF macro to more implementations of __typeof__ and standardized equivalents on C23 and C++11. On MSVC, __typeof__ is enabled through _MSC_VER check; for others, an autoconf probe is implemented. --- Include/pyport.h | 9 +++++++-- configure | 30 ++++++++++++++++++++++++++++++ configure.ac | 13 +++++++++++++ pyconfig.h.in | 3 +++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 2b6bd4c21110e5..9ed83765defc75 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -554,9 +554,14 @@ extern "C" { // // Example: _Py_TYPEOF(x) x_copy = (x); // -// The macro is only defined if GCC or clang compiler is used. -#if defined(__GNUC__) || defined(__clang__) +// Defined if __typeof__ or its equivalents are available. +#if defined(__GNUC__) || defined(__clang__) || defined(HAVE_TYPEOF) || \ + (defined(_MSC_VER) && _MSC_VER >= 1939) # define _Py_TYPEOF(expr) __typeof__(expr) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +# define _Py_TYPEOF(expr) typeof(expr) +#elif defined(__cplusplus) && __cplusplus >= 201103 +# define _Py_TYPEOF(expr) decltype(expr) #endif diff --git a/configure b/configure index 19786f18e61726..1a6ba2b1204808 100755 --- a/configure +++ b/configure @@ -27661,6 +27661,36 @@ printf "%s\n" "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports __typeof__" >&5 +printf %s "checking whether $CC supports __typeof__... " >&6; } +if test ${ac_cv_typeof+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int i; +__typeof__(i) *p = &i; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_typeof=yes +else $as_nop + ac_cv_typeof=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_typeof" >&5 +printf "%s\n" "$ac_cv_typeof" >&6; } +if test "$ac_cv_typeof" = yes +then + +printf "%s\n" "#define HAVE_TYPEOF 1" >>confdefs.h + +fi + case $ac_sys_system in AIX*) diff --git a/configure.ac b/configure.ac index df146cc9cf0b75..6311aa60de3ca1 100644 --- a/configure.ac +++ b/configure.ac @@ -6983,6 +6983,19 @@ case "$ac_cv_computed_gotos" in yes*) [Define if the C compiler supports computed gotos.]) esac +AC_CACHE_CHECK([whether $CC supports __typeof__], [ac_cv_typeof], +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +int i; +__typeof__(i) *p = &i; +]])], +[ac_cv_typeof=yes], +[ac_cv_typeof=no])) +if test "$ac_cv_typeof" = yes +then + AC_DEFINE([HAVE_TYPEOF], [1], + [Define if the C compiler supports __typeof__(expr)]) +fi + case $ac_sys_system in AIX*) AC_DEFINE([HAVE_BROKEN_PIPE_BUF], [1], diff --git a/pyconfig.h.in b/pyconfig.h.in index 8fbba7ed3b949e..9d81b390cec0f3 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1498,6 +1498,9 @@ /* Define to 1 if you have the `ttyname' function. */ #undef HAVE_TTYNAME +/* Define if the C compiler supports __typeof__(expr) */ +#undef HAVE_TYPEOF + /* Define to 1 if you don't have `tm_zone' but do have the external array `tzname'. */ #undef HAVE_TZNAME