v10-0004-Add-C-version-of-__builtin_types_compatible_p.patch
text/x-patch
Filename: v10-0004-Add-C-version-of-__builtin_types_compatible_p.patch
Type: text/x-patch
Part: 3
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 v10-0004
Subject: Add C++ version of __builtin_types_compatible_p
| File | + | − |
|---|---|---|
| src/include/c.h | 22 | 0 |
| src/test/modules/test_cplusplusext/test_cplusplusext.cpp | 19 | 1 |
From 437a8aece153c5dc24c0e2708c034fe1718ea3bf Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Fri, 13 Feb 2026 09:39:34 +0100
Subject: [PATCH v10 4/4] Add C++ version of __builtin_types_compatible_p
StaticAssertVariableIsOfType would fail to compile in C++ extensions if
meson/autoconf has detected HAVE__BUILTIN_TYPES_COMPATIBLE_P to be true
for the C compiler. Basically equivalent to the PG_PRINTF_ATTRIBUTE
situation in 0909380e4c9.
This fixes that problem by defining __builtin_types_compatible_p in C++
using an equivalent STL constructs.
---
src/include/c.h | 22 +++++++++++++++++++
.../test_cplusplusext/test_cplusplusext.cpp | 20 ++++++++++++++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/src/include/c.h b/src/include/c.h
index c92b214f6b0..ba629a3503b 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -80,6 +80,12 @@
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
+#ifdef __cplusplus
+extern "C++"
+{
+#include <type_traits>
+}
+#endif
#ifdef ENABLE_NLS
#include <libintl.h>
#endif
@@ -443,7 +449,23 @@
#ifndef HAVE_TYPEOF
#define HAVE_TYPEOF 1
#endif
+/*
+ * Provide __builtin_types_compatible_p for C++ by comparing types with
+ * std::is_same after stripping cv-qualifiers. The second branch handles
+ * GCC's special case where an incomplete array (e.g. int[]) is considered
+ * compatible with a complete array of the same element type (e.g. int[3]).
+ */
+#define __builtin_types_compatible_p(x, y) \
+ (std::is_same<std::remove_cv_t<x>, std::remove_cv_t<y>>::value || \
+ (std::is_array<x>::value && std::is_array<y>::value && \
+ (std::extent<x>::value == 0 || std::extent<y>::value == 0) && \
+ std::is_same<std::remove_cv_t<std::remove_extent_t<x>>, \
+ std::remove_cv_t<std::remove_extent_t<y>>>::value))
+#ifndef HAVE__BUILTIN_TYPES_COMPATIBLE_P
+#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1
#endif
+#endif
+
/*
* CppAsString
diff --git a/src/test/modules/test_cplusplusext/test_cplusplusext.cpp b/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
index ea04a761184..936ca422c76 100644
--- a/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
+++ b/src/test/modules/test_cplusplusext/test_cplusplusext.cpp
@@ -34,11 +34,14 @@ StaticAssertDecl(sizeof(int32) == 4, "int32 should be 4 bytes");
extern "C" Datum
test_cplusplus_add(PG_FUNCTION_ARGS)
{
- int32 a = PG_GETARG_INT32(0);
+ const int32 a = PG_GETARG_INT32(0);
int32 b = PG_GETARG_INT32(1);
+ const char *p = "";
RangeTblRef *node = makeNode(RangeTblRef);
RangeTblRef *copy = copyObject(node);
List *list = list_make1(node);
+ const int32 int_array[3] = {0};
+ extern int32 incomplete_array[];
foreach_ptr(RangeTblRef, rtr, list)
{
@@ -52,6 +55,21 @@ test_cplusplus_add(PG_FUNCTION_ARGS)
StaticAssertStmt(sizeof(int32) == 4, "int32 should be 4 bytes");
(void) StaticAssertExpr(sizeof(int64) == 8, "int64 should be 8 bytes");
+ StaticAssertVariableIsOfType(a, int32);
+ StaticAssertVariableIsOfType(a, const int32);
+ StaticAssertVariableIsOfType(b, const int32);
+ StaticAssertVariableIsOfType(int_array, int32[3]);
+ StaticAssertVariableIsOfType(int_array, const int32[3]);
+ StaticAssertVariableIsOfType(p, const char *);
+ StaticAssertVariableIsOfTypeMacro(a, int32);
+ StaticAssertVariableIsOfTypeMacro(a, const int32);
+ StaticAssertVariableIsOfTypeMacro(b, int32);
+ StaticAssertVariableIsOfTypeMacro(int_array, int32[3]);
+ StaticAssertVariableIsOfTypeMacro(int_array, const int32[3]);
+ StaticAssertVariableIsOfTypeMacro(p, const char *);
+ /* incomplete array matches complete array type */
+ StaticAssertVariableIsOfType(incomplete_array, int32[3]);
+ StaticAssertVariableIsOfTypeMacro(incomplete_array, int32[3]);
list_free(list);
pfree(node);
--
2.53.0