0001-Change-copyObject-to-use-typeof_unqual.patch
text/plain
Filename: 0001-Change-copyObject-to-use-typeof_unqual.patch
Type: text/plain
Part: 0
Message:
Re: Make copyObject work in C++
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 0001
Subject: Change copyObject() to use typeof_unqual
| File | + | − |
|---|---|---|
| config/c-compiler.m4 | 25 | 0 |
| configure | 42 | 0 |
| configure.ac | 1 | 0 |
| meson.build | 24 | 0 |
| src/include/nodes/nodes.h | 2 | 2 |
| src/include/pg_config.h.in | 7 | 0 |
From 1e733f16f116be638cbd4f6a359a01541c9a5d24 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 8 Dec 2025 08:33:18 +0100
Subject: [PATCH] Change copyObject() to use typeof_unqual
The new implementation ensures that the result of copyObject() is not
const-qualified when the input is. This was previously incorrect,
since the point of copyObject() is to make a copy to mutate, but
apparently no code ran into it.
---
config/c-compiler.m4 | 25 +++++++++++++++++++++++
configure | 42 ++++++++++++++++++++++++++++++++++++++
configure.ac | 1 +
meson.build | 24 ++++++++++++++++++++++
src/include/nodes/nodes.h | 4 ++--
src/include/pg_config.h.in | 7 +++++++
6 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 236a59e8536..8ee860c9091 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -160,6 +160,31 @@ if test "$pgac_cv_c_typeof" != no; then
fi])# PGAC_C_TYPEOF
+# PGAC_C_TYPEOF_UNQUAL
+# --------------------
+# 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.
+#
+AC_DEFUN([PGAC_C_TYPEOF_UNQUAL],
+[AC_CACHE_CHECK(for typeof_unqual, pgac_cv_c_typeof_unqual,
+[pgac_cv_c_typeof_unqual=no
+for pgac_kw in typeof_unqual __typeof_unqual__; do
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
+[int x = 0;
+$pgac_kw(x) y;
+y = x;
+return y;])],
+[pgac_cv_c_typeof_unqual=$pgac_kw])
+ test "$pgac_cv_c_typeof_unqual" != no && break
+done])
+if test "$pgac_cv_c_typeof_unqual" != no; then
+ AC_DEFINE(HAVE_TYPEOF_UNQUAL, 1,
+ [Define to 1 if your compiler understands `typeof_unqual' or something similar.])
+ if test "$pgac_cv_c_typeof_unqual" != typeof_unqual; then
+ AC_DEFINE_UNQUOTED(typeof_unqual, $pgac_cv_c_typeof_unqual, [Define to how the compiler spells `typeof_unqual'.])
+ fi
+fi])# PGAC_C_TYPEOF_UNQUAL
+
# PGAC_C_TYPES_COMPATIBLE
# -----------------------
diff --git a/configure b/configure
index 3a0ed11fa8e..af856b20f0b 100755
--- a/configure
+++ b/configure
@@ -14787,6 +14787,48 @@ _ACEOF
fi
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeof_unqual" >&5
+$as_echo_n "checking for typeof_unqual... " >&6; }
+if ${pgac_cv_c_typeof_unqual+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ pgac_cv_c_typeof_unqual=no
+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;
+y = x;
+return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ pgac_cv_c_typeof_unqual=$pgac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$pgac_cv_c_typeof_unqual" != no && break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_c_typeof_unqual" >&5
+$as_echo "$pgac_cv_c_typeof_unqual" >&6; }
+if test "$pgac_cv_c_typeof_unqual" != no; then
+
+$as_echo "#define HAVE_TYPEOF_UNQUAL 1" >>confdefs.h
+
+ if test "$pgac_cv_c_typeof_unqual" != typeof_unqual; then
+
+cat >>confdefs.h <<_ACEOF
+#define typeof_unqual $pgac_cv_c_typeof_unqual
+_ACEOF
+
+ 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; }
if ${pgac_cv__types_compatible+:} false; then :
diff --git a/configure.ac b/configure.ac
index c2413720a18..8eced24beb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1676,6 +1676,7 @@ AC_C_INLINE
PGAC_PRINTF_ARCHETYPE
PGAC_C_STATIC_ASSERT
PGAC_C_TYPEOF
+PGAC_C_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 6e7ddd74683..85b98ad81db 100644
--- a/meson.build
+++ b/meson.build
@@ -2818,6 +2818,30 @@ int main(void)
endif
endforeach
+# 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.
+foreach kw : ['typeof_unqual', '__typeof_unqual__']
+ if cc.compiles('''
+int main(void)
+{
+ int x = 0;
+ @0@(x) y;
+ y = x;
+ return y;
+}
+'''.format(kw),
+ name: kw,
+ args: test_c_args, include_directories: postgres_inc)
+
+ cdata.set('HAVE_TYPEOF_UNQUAL', 1)
+ if kw != 'typeof_unqual'
+ cdata.set('typeof_unqual', kw)
+ endif
+
+ break
+ endif
+endforeach
+
# Even though restrict is in C99 and should be supported by all
# supported compilers, this indirection is useful because __restrict
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index fb3957e75e5..0ac0be1b288 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -226,8 +226,8 @@ extern int16 *readAttrNumberCols(int numCols);
extern void *copyObjectImpl(const void *from);
/* cast result back to argument type, if supported by compiler */
-#ifdef HAVE_TYPEOF
-#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj))
+#ifdef HAVE_TYPEOF_UNQUAL
+#define copyObject(obj) ((typeof_unqual(*(obj)) *) copyObjectImpl(obj))
#else
#define copyObject(obj) copyObjectImpl(obj)
#endif
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b0b0cfdaf79..503467ca092 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -472,6 +472,10 @@
/* Define to 1 if your compiler understands `typeof' or something similar. */
#undef HAVE_TYPEOF
+/* Define to 1 if your compiler understands `typeof_unqual' or something
+ similar. */
+#undef HAVE_TYPEOF_UNQUAL
+
/* Define to 1 if you have the <uchar.h> header file. */
#undef HAVE_UCHAR_H
@@ -815,3 +819,6 @@
/* Define to how the compiler spells `typeof'. */
#undef typeof
+
+/* Define to how the compiler spells `typeof_unqual'. */
+#undef typeof_unqual
--
2.52.0