On Fri, 27 Mar 2026 at 12:23, Peter Eisentraut <[email protected]> wrote:
Here is another tidied up patch set for this.  I didn't go quite as far
as enabling C++20 by default in meson.build, this would just take more
time to work out and test all the different combinations, but I added
the flag to the Cirrus CI task, since there we know what compiler we have.

I think 0001 and 0002 are good.

0003 seems awkward though. Attached is an approach that I think is
better: It actually checks for the required featureset and adds the
necessary flags to the compiler.

I also added a small patch in 0004 to align configure and meson
behaviour when no sufficiently modern compiler is found.
From 6b04f2bc87231998946ff0736013a98c9f23df2c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Fri, 27 Mar 2026 11:45:36 +0100
Subject: [PATCH v12 1/4] meson: Make room for C++-only warning flags for MSVC

Refactor the MSVC warning option handling to have a list of common
flags and lists of flags specific to C and C++.
---
 meson.build | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/meson.build b/meson.build
index ea31cbce9c0..42b0a9a6a71 100644
--- a/meson.build
+++ b/meson.build
@@ -2293,27 +2293,42 @@ endforeach
 
 
 if cc.get_id() == 'msvc'
-  cflags_warn += [
+  msvc_common_warning_flags = [
+    # Disable warnings in system headers
+    '/external:anglebrackets',
+    '/external:W0',
+
     # Warnings to disable:
-    # from /W1:
-    '/wd4090', # different 'modifier' qualifiers
     # from /W2:
     '/wd4244', # conversion from 'type1' to 'type2', possible loss of data
+
+    # Additional warnings to enable:
+    '/w24062', # enumerator 'identifier' in switch of enum 'enumeration' is not handled [like -Wswitch]
+    '/w24102', # unreferenced label [like -Wunused-label]
+  ]
+
+  msvc_c_warning_flags = [
+    # Warnings to disable:
+    # from /W1:
+    '/wd4090', # different 'modifier' qualifiers
     # from /W3:
     '/wd4018', # signed/unsigned mismatch
     '/wd4101', # unreferenced local variable [like -Wunused-variable, but there is no "unused" attribute, so too noisy]
     '/wd4267', # conversion from 'size_t' to 'type', possible loss of data
 
     # Additional warnings to enable:
-    '/w24062', # enumerator 'identifier' in switch of enum 'enumeration' is not handled [like -Wswitch]
-    '/w24102', # unreferenced label [like -Wunused-label]
     '/w24255', # 'function' : no function prototype given: converting '()' to '(void)' [like -Wstrict-prototypes]
+  ]
 
-    # Disable warnings in system headers
-    '/external:anglebrackets',
-    '/external:W0',
+  msvc_cxx_warning_flags = [
   ]
 
+  cflags_warn += msvc_common_warning_flags
+  cflags_warn += msvc_c_warning_flags
+
+  cxxflags_warn += msvc_common_warning_flags
+  cxxflags_warn += msvc_cxx_warning_flags
+
   cppflags += [
     '/DWIN32',
     '/DWINDOWS',

base-commit: 10e4d8aaf46fb46b8b78e026560b68af84a6495b
-- 
2.53.0

From 366dfbc11fd047f75107a87023b39a58fa7a2326 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 26 Mar 2026 08:35:45 +0100
Subject: [PATCH v12 2/4] Disable some C++ warnings in MSVC

Flexible array members, as used in many PostgreSQL header files, are
not a C++ feature.  MSVC warns about these.  Disable the
warning.  (GCC and Clang accept them, but they would warn in -pedantic
mode.)
---
 meson.build | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/meson.build b/meson.build
index 42b0a9a6a71..64a5bb888d6 100644
--- a/meson.build
+++ b/meson.build
@@ -2321,6 +2321,9 @@ if cc.get_id() == 'msvc'
   ]
 
   msvc_cxx_warning_flags = [
+    # Warnings to disable:
+    # from /W2:
+    '/wd4200', # nonstandard extension used: zero-sized array in struct/union [widely used in PostgreSQL C headers]
   ]
 
   cflags_warn += msvc_common_warning_flags
-- 
2.53.0

From df6d9e8d1bb955d9cffe3095cc27d4209de1ce33 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <[email protected]>
Date: Sun, 29 Mar 2026 13:01:37 +0200
Subject: [PATCH v12 3/4] Add support for C++ extensions with MSVC

To build C++ extensions we need support for designated initializers,
because PG_MODULE_MAGIC uses it. Designated initializers only got
standardized in C++20. In GCC and Clang they also work when using
earlier C++ versions, but MSVC really only supports them when its
configured to be in C++20 mode or higher.

This extends C++11 feature test to also check for designated initializer
support.

When passing both -pedantic and -Werror even Clang and GCC can fail this
new feature test if they're old enough that they don't compile with
C++20 by default. So this also changes meson and configure to try C++20
if using C++11 didn't work. Before this patch this such a setup would
pass the C++11 check but would then fail to compile test_cplusplusext.
---
 configure.ac                                  | 13 ++++++----
 doc/src/sgml/xfunc.sgml                       |  5 ++++
 meson.build                                   | 26 +++++++++++--------
 .../modules/test_cplusplusext/meson.build     |  5 ----
 4 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2baac5e9da7..e4570a805c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -398,17 +398,20 @@ AC_SUBST(have_cxx)
 
 if test "$have_cxx" = yes; then
 
-# Detect option needed for C++11
-AC_MSG_CHECKING([for $CXX option to accept ISO C++11])
+# Detect option needed for C++11 with designated initializers. We need
+# designated initializers because we use them in many of our headers, including
+# in the PG_MODULE_MAGIC definition.
+AC_MSG_CHECKING([for $CXX option to accept ISO C++11 with designated initializers])
 AC_CACHE_VAL([pgac_cv_prog_cxx_cxx11],
 [pgac_cv_prog_cxx_cxx11=no
 pgac_save_CXX=$CXX
 AC_LANG_PUSH([C++])
-for pgac_arg in '' '-std=gnu++11' '-std=c++11'; do
+for pgac_arg in '' '-std=gnu++11' '-std=c++11' '-std=gnu++20' '-std=c++20'; do
   CXX="$pgac_save_CXX $pgac_arg"
   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#if !defined __cplusplus || __cplusplus < 201103L
 # error "Compiler does not advertise C++11 conformance"
-#endif]])], [[pgac_cv_prog_cxx_cxx11=$pgac_arg]])
+#endif
+struct S { int x; } s = { .x = 1 };]])], [[pgac_cv_prog_cxx_cxx11=$pgac_arg]])
   test x"$pgac_cv_prog_cxx_cxx11" != x"no" && break
 done
 AC_LANG_POP([C++])
@@ -416,7 +419,7 @@ CXX=$pgac_save_CXX])
 
 if test x"$pgac_cv_prog_cxx_cxx11" = x"no"; then
   AC_MSG_RESULT([unsupported])
-  AC_MSG_WARN([C++ compiler "$CXX" does not support C++11])
+  AC_MSG_WARN([C++ compiler "$CXX" does not support C++11 with designated initializers])
   have_cxx=no
 elif test x"$pgac_cv_prog_cxx_cxx11" = x""; then
   AC_MSG_RESULT([none needed])
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 70e815b8a2c..6895fe483c1 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -4026,6 +4026,11 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,
 
      <itemizedlist>
       <listitem>
+       <para>
+         You need a C++ compiler that supports C++11 and designated
+         initializers (GCC and Clang support this in C++11 mode, but MSVC only
+         supports it in C++20 mode).
+       </para>
        <para>
          All functions accessed by the backend must present a C interface
          to the backend;  these C functions can then call C++ functions.
diff --git a/meson.build b/meson.build
index 64a5bb888d6..bcad5f4fc01 100644
--- a/meson.build
+++ b/meson.build
@@ -647,29 +647,33 @@ if not cc.compiles(c11_test, name: 'C11')
 endif
 
 
-# Do we need an option to enable C++11?
-cxx11_test = '''
+# Do we need an option to enable C++11 and/or designated initializers? We need
+# designated initiliazers because we use them in many of our headers, including
+# in the PG_MODULE_MAGIC definition. Clang and gcc support designated
+# initializers in C++11 mode, but MSVC only supports them in C++20 mode.
+cxx_features_test = '''
 #if !defined __cplusplus || __cplusplus < 201103L
 # error "Compiler does not advertise C++11 conformance"
 #endif
+struct S { int x; } s = { .x = 1 };
 '''
 
-if have_cxx and not cxx.compiles(cxx11_test, name: 'C++11')
-  cxx11_ok = false
+if have_cxx and not cxx.compiles(cxx_features_test, name: 'C++11 with designated initializers')
+  cxx_features_ok = false
   if cxx.get_id() == 'msvc'
-    cxx11_test_args = ['/std:c++14']  # oldest version supported
+    cxx_features_test_args = ['/std:c++20']
   else
-    cxx11_test_args = ['-std=gnu++11', '-std=c++11']
+    cxx_features_test_args = ['-std=gnu++11', '-std=c++11', '-std=gnu++20', 'std=c++20']
   endif
-  foreach arg : cxx11_test_args
-    if cxx.compiles(cxx11_test, name: 'C++11 with @0@'.format(arg), args: [arg])
-      cxx11_ok = true
+  foreach arg : cxx_features_test_args
+    if cxx.compiles(cxx_features_test, name: 'C++11 with designated initializers with @0@'.format(arg), args: [arg])
+      cxx_features_ok = true
       cxxflags += arg
       break
     endif
   endforeach
-  if not cxx11_ok
-    error('C++ compiler does not support C++11')
+  if not cxx_features_ok
+    error('C++ compiler does not support C++11 with designated initializers')
   endif
 endif
 
diff --git a/src/test/modules/test_cplusplusext/meson.build b/src/test/modules/test_cplusplusext/meson.build
index d13210ca593..24a9cf16dca 100644
--- a/src/test/modules/test_cplusplusext/meson.build
+++ b/src/test/modules/test_cplusplusext/meson.build
@@ -4,11 +4,6 @@ if not have_cxx
   subdir_done()
 endif
 
-# Currently not supported, to be fixed.
-if cc.get_id() == 'msvc'
-  subdir_done()
-endif
-
 test_cplusplusext_sources = files(
   'test_cplusplusext.cpp',
 )
-- 
2.53.0

From 3eeeabc4335d2ceef777b20bb1460a38a82baf2d Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <[email protected]>
Date: Mon, 30 Mar 2026 00:45:53 +0200
Subject: [PATCH v12 4/4] meson: Consider an insufficient C++ compiler a
 warning

Meson and configure were handling the case of a C++ compiler with an
insufficient feature set differently. In configure, it would be a
warning, but meson would throw a hard error. This makes it a warning in
meson too.
---
 meson.build | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index bcad5f4fc01..ef1d7ed9a57 100644
--- a/meson.build
+++ b/meson.build
@@ -673,7 +673,8 @@ if have_cxx and not cxx.compiles(cxx_features_test, name: 'C++11 with designated
     endif
   endforeach
   if not cxx_features_ok
-    error('C++ compiler does not support C++11 with designated initializers')
+    warning('C++ compiler does not support C++11 with designated initializers')
+    have_cxx = false
   endif
 endif
 
-- 
2.53.0

Reply via email to