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
