v2-0001-Check-CLANG-for-typeof_unqual.patch
text/x-patch
Filename: v2-0001-Check-CLANG-for-typeof_unqual.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0001
Subject: Check CLANG for typeof_unqual
| File | + | − |
|---|---|---|
| config/c-compiler.m4 | 37 | 8 |
| config/test_typeof_unqual.c | 20 | 0 |
| configure | 57 | 8 |
| configure.ac | 6 | 0 |
| meson.build | 26 | 6 |
| src/backend/jit/llvm/meson.build | 1 | 1 |
| src/include/c.h | 16 | 0 |
| src/include/pg_config.h.in | 7 | 0 |
From 2058a59b52b17ce15752b7f488082929967429c3 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Sun, 15 Mar 2026 22:39:45 +0100
Subject: [PATCH v2] Check CLANG for typeof_unqual
Turns out that CLANG on the buildfarm is sometimes significantly older
than the CC compiler, and thus supports different features. This
explicitly checks typeof_unqual support for CLANG, because that's the
feature that sometimes seems to be lacking in practice.
---
config/c-compiler.m4 | 45 ++++++++++++++++++----
config/test_typeof_unqual.c | 20 ++++++++++
configure | 65 ++++++++++++++++++++++++++++----
configure.ac | 6 +++
meson.build | 32 +++++++++++++---
src/backend/jit/llvm/meson.build | 2 +-
src/include/c.h | 16 ++++++++
src/include/pg_config.h.in | 7 ++++
8 files changed, 170 insertions(+), 23 deletions(-)
create mode 100644 config/test_typeof_unqual.c
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 88333ef301d..6ae57199b1c 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -181,16 +181,12 @@ fi])# PGAC_C_TYPEOF
# Check if the C compiler understands typeof_unqual or a variant. Define
# HAVE_TYPEOF_UNQUAL if so, and define 'typeof_unqual' to the actual key word.
#
+# Test with a void pointer, because MSVC doesn't handle that, and we
+# need that for copyObject().
AC_DEFUN([PGAC_C_TYPEOF_UNQUAL],
[AC_CACHE_CHECK(for typeof_unqual, pgac_cv_c_typeof_unqual,
[pgac_cv_c_typeof_unqual=no
-# Test the underscore variant first so that there is a higher chance
-# that clang used for bitcode also supports it, since we don't test
-# that separately.
-#
-# Test with a void pointer, because MSVC doesn't handle that, and we
-# need that for copyObject().
-for pgac_kw in __typeof_unqual__ typeof_unqual; do
+for pgac_kw in typeof_unqual __typeof_unqual__; do
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[int x = 0;
$pgac_kw(x) y;
@@ -248,7 +244,7 @@ AC_DEFUN([PGAC_CXX_TYPEOF_UNQUAL],
[AC_CACHE_CHECK(for C++ typeof_unqual, pgac_cv_cxx_typeof_unqual,
[pgac_cv_cxx_typeof_unqual=no
AC_LANG_PUSH(C++)
-for pgac_kw in __typeof_unqual__ typeof_unqual; do
+for pgac_kw in typeof_unqual __typeof_unqual__; do
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[int x = 0;
$pgac_kw(x) y;
@@ -270,6 +266,39 @@ if test "$pgac_cv_cxx_typeof_unqual" != no; then
fi])# PGAC_CXX_TYPEOF_UNQUAL
+# PGAC_CLANG_TYPEOF_UNQUAL
+# ------------------------
+# Check if CLANG (used for LLVM bitcode compilation) understands
+# typeof_unqual or a variant. Define HAVE_CLANG_TYPEOF_UNQUAL if so, and
+# define 'pg_clang_typeof_unqual' to the actual key word.
+#
+AC_DEFUN([PGAC_CLANG_TYPEOF_UNQUAL],
+[AC_CACHE_CHECK(for CLANG typeof_unqual, pgac_cv_clang_typeof_unqual,
+[pgac_cv_clang_typeof_unqual=no
+pgac_save_CC=$CC
+CC="$CLANG"
+for pgac_kw in typeof_unqual __typeof_unqual__; do
+ _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
+[int x = 0;
+$pgac_kw(x) y;
+const void *a;
+void *b;
+y = x;
+b = ($pgac_kw(*a) *) a;
+return y;])],
+[pgac_cv_clang_typeof_unqual=$pgac_kw])
+ test "$pgac_cv_clang_typeof_unqual" != no && break
+done
+CC="$pgac_save_CC"])
+if test "$pgac_cv_clang_typeof_unqual" != no; then
+ AC_DEFINE(HAVE_CLANG_TYPEOF_UNQUAL, 1,
+ [Define to 1 if CLANG for bitcode understands `typeof_unqual' or something similar.])
+ if test "$pgac_cv_clang_typeof_unqual" != typeof_unqual; then
+ AC_DEFINE_UNQUOTED(pg_clang_typeof_unqual, $pgac_cv_clang_typeof_unqual, [Define to how CLANG for bitcode spells `typeof_unqual'.])
+ fi
+fi])# PGAC_CLANG_TYPEOF_UNQUAL
+
+
# PGAC_C_TYPES_COMPATIBLE
# -----------------------
diff --git a/config/test_typeof_unqual.c b/config/test_typeof_unqual.c
new file mode 100644
index 00000000000..108c8f5468b
--- /dev/null
+++ b/config/test_typeof_unqual.c
@@ -0,0 +1,20 @@
+/*
+ * Test program for typeof_unqual detection.
+ *
+ * Used by meson.build to check whether clang used for LLVM bitcode
+ * compilation supports typeof_unqual or a variant. Pass -DKW=<keyword>
+ * to test a specific spelling.
+ */
+int
+main(void)
+{
+ int x = 0;
+
+ KW(x) y;
+ const void *a;
+ void *b;
+
+ y = x;
+ b = (KW(*a) *) a;
+ return y;
+}
diff --git a/configure b/configure
index 4c789bd9289..80e29ff3ead 100755
--- a/configure
+++ b/configure
@@ -7077,6 +7077,9 @@ fi
if test "$with_llvm" = yes ; then
CLANGXX="$CLANG -xc++"
+ BITCODE_CFLAGS="$BITCODE_CFLAGS -DPG_COMPILING_BITCODE"
+ BITCODE_CXXFLAGS="$BITCODE_CXXFLAGS -DPG_COMPILING_BITCODE"
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -fno-strict-aliasing, for BITCODE_CFLAGS" >&5
$as_echo_n "checking whether ${CLANG} supports -fno-strict-aliasing, for BITCODE_CFLAGS... " >&6; }
if ${pgac_cv_prog_CLANG_cflags__fno_strict_aliasing+:} false; then :
@@ -15107,13 +15110,7 @@ if ${pgac_cv_c_typeof_unqual+:} false; then :
$as_echo_n "(cached) " >&6
else
pgac_cv_c_typeof_unqual=no
-# Test the underscore variant first so that there is a higher chance
-# that clang used for bitcode also supports it, since we don't test
-# that separately.
-#
-# Test with a void pointer, because MSVC doesn't handle that, and we
-# need that for copyObject().
-for pgac_kw in __typeof_unqual__ typeof_unqual; do
+for pgac_kw in typeof_unqual __typeof_unqual__; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -15164,7 +15161,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-for pgac_kw in __typeof_unqual__ typeof_unqual; do
+for pgac_kw in typeof_unqual __typeof_unqual__; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -15208,6 +15205,58 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
fi
+fi
+if test "$with_llvm" = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CLANG typeof_unqual" >&5
+$as_echo_n "checking for CLANG typeof_unqual... " >&6; }
+if ${pgac_cv_clang_typeof_unqual+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ pgac_cv_clang_typeof_unqual=no
+pgac_save_CC=$CC
+CC="$CLANG"
+for pgac_kw in typeof_unqual __typeof_unqual__; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int x = 0;
+$pgac_kw(x) y;
+const void *a;
+void *b;
+y = x;
+b = ($pgac_kw(*a) *) a;
+return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ pgac_cv_clang_typeof_unqual=$pgac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$pgac_cv_clang_typeof_unqual" != no && break
+done
+CC="$pgac_save_CC"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_clang_typeof_unqual" >&5
+$as_echo "$pgac_cv_clang_typeof_unqual" >&6; }
+if test "$pgac_cv_clang_typeof_unqual" != no; then
+
+$as_echo "#define HAVE_CLANG_TYPEOF_UNQUAL 1" >>confdefs.h
+
+ if test "$pgac_cv_clang_typeof_unqual" != typeof_unqual; then
+
+cat >>confdefs.h <<_ACEOF
+#define pg_clang_typeof_unqual $pgac_cv_clang_typeof_unqual
+_ACEOF
+
+ fi
+fi
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_types_compatible_p" >&5
$as_echo_n "checking for __builtin_types_compatible_p... " >&6; }
diff --git a/configure.ac b/configure.ac
index 9edffe481a6..69ad014238f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -686,6 +686,9 @@ AC_SUBST(CXXFLAGS_SL_MODULE)
if test "$with_llvm" = yes ; then
CLANGXX="$CLANG -xc++"
+ BITCODE_CFLAGS="$BITCODE_CFLAGS -DPG_COMPILING_BITCODE"
+ BITCODE_CXXFLAGS="$BITCODE_CXXFLAGS -DPG_COMPILING_BITCODE"
+
PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-fno-strict-aliasing])
PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANGXX, BITCODE_CXXFLAGS, [-fno-strict-aliasing])
PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-fwrapv])
@@ -1734,6 +1737,9 @@ PGAC_C_TYPEOF
PGAC_CXX_TYPEOF
PGAC_C_TYPEOF_UNQUAL
PGAC_CXX_TYPEOF_UNQUAL
+AS_IF([test "$with_llvm" = yes], [
+ PGAC_CLANG_TYPEOF_UNQUAL
+])
PGAC_C_TYPES_COMPATIBLE
PGAC_C_BUILTIN_CONSTANT_P
PGAC_C_BUILTIN_OP_OVERFLOW
diff --git a/meson.build b/meson.build
index f7a87edcc94..f17970f1ae2 100644
--- a/meson.build
+++ b/meson.build
@@ -2969,13 +2969,9 @@ endif
# Check if the C compiler understands typeof_unqual or a variant. Define
# HAVE_TYPEOF_UNQUAL if so, and define 'typeof_unqual' to the actual key word.
#
-# Test the underscore variant first so that there is a higher chance
-# that clang used for bitcode also supports it, since we don't test
-# that separately.
-#
# Test with a void pointer, because MSVC doesn't handle that, and we
# need that for copyObject().
-foreach kw : ['__typeof_unqual__', 'typeof_unqual']
+foreach kw : ['typeof_unqual', '__typeof_unqual__']
if cc.compiles('''
int main(void)
{
@@ -3002,7 +2998,7 @@ endforeach
# Check if the C++ compiler understands typeof_unqual or a variant.
if have_cxx
- foreach kw : ['__typeof_unqual__', 'typeof_unqual']
+ foreach kw : ['typeof_unqual', '__typeof_unqual__']
if cxx.compiles('''
int main(void)
{
@@ -3028,6 +3024,30 @@ int main(void)
endforeach
endif
+# Check if CLANG (used for LLVM bitcode compilation) understands
+# typeof_unqual or a variant. We use run_command with a test file
+# because clang is a program, not a meson compiler object, so
+# cc.compiles() cannot be used.
+if llvm.found()
+ clang_typeof_unqual_found = false
+ foreach kw : ['typeof_unqual', '__typeof_unqual__']
+ if not clang_typeof_unqual_found
+ r = run_command(clang, '-fsyntax-only', '-DKW=' + kw,
+ files('config/test_typeof_unqual.c'), check: false)
+ if r.returncode() == 0
+ message('CLANG supports ' + kw)
+ clang_typeof_unqual_found = true
+ cdata.set('HAVE_CLANG_TYPEOF_UNQUAL', 1)
+ if kw != 'typeof_unqual'
+ cdata.set('pg_clang_typeof_unqual', kw)
+ endif
+ else
+ message('CLANG does not support ' + kw)
+ endif
+ endif
+ endforeach
+endif
+
# MSVC doesn't cope well with defining restrict to __restrict, the
# spelling it understands, because it conflicts with
diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build
index 7df8453ad6f..7270143771e 100644
--- a/src/backend/jit/llvm/meson.build
+++ b/src/backend/jit/llvm/meson.build
@@ -60,7 +60,7 @@ endif
# XXX: Need to determine proper version of the function cflags for clang
-bitcode_cflags = ['-fno-strict-aliasing', '-fwrapv']
+bitcode_cflags = ['-DPG_COMPILING_BITCODE', '-fno-strict-aliasing', '-fwrapv']
bitcode_cflags += get_option('c_args')
bitcode_cflags += cppflags
diff --git a/src/include/c.h b/src/include/c.h
index 29fef2f54e1..e0dfb897529 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -466,6 +466,22 @@ extern "C++"
#endif
#endif /* __cplusplus */
+/*
+ * Override typeof_unqual for LLVM bitcode compilation when CLANG doesn't
+ * support the same keyword as CC. Analogous to the C++ override above.
+ * PG_COMPILING_BITCODE is defined in BITCODE_CFLAGS.
+ */
+#if defined(PG_COMPILING_BITCODE) && !defined(__cplusplus)
+#undef HAVE_TYPEOF_UNQUAL
+#undef typeof_unqual
+#ifdef pg_clang_typeof_unqual
+#define typeof_unqual(x) pg_clang_typeof_unqual(x)
+#define HAVE_TYPEOF_UNQUAL 1
+#elif defined(HAVE_CLANG_TYPEOF_UNQUAL)
+#define HAVE_TYPEOF_UNQUAL 1
+#endif
+#endif /* PG_COMPILING_BITCODE && !__cplusplus */
+
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 79379a4d125..b1c20ce754a 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -54,6 +54,10 @@
/* Define to 1 if you have the `backtrace_symbols' function. */
#undef HAVE_BACKTRACE_SYMBOLS
+/* Define to 1 if CLANG for bitcode understands `typeof_unqual' or something
+ similar. */
+#undef HAVE_CLANG_TYPEOF_UNQUAL
+
/* Define to 1 if your compiler handles computed gotos. */
#undef HAVE_COMPUTED_GOTO
@@ -789,6 +793,9 @@
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
+/* Define to how CLANG for bitcode spells `typeof_unqual'. */
+#undef pg_clang_typeof_unqual
+
/* Define to how the C++ compiler spells `typeof'. */
#undef pg_cxx_typeof
base-commit: a793677e57bc27c674cb94b230164b2c28f4cbae
--
2.53.0