From 54edfc613947d93a3250b374c81df9d335de2a96 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 22 Mar 2021 13:10:02 +0100 Subject: [PATCH] libnm: improve detection for C11 _Generic() support Older gcc doesn't like this: ../src/libnm-core-impl/nm-setting-wired.c:132:49: error: controlling expression type 'const char *const [31]' not compatible with any generic association type && (nm_utils_strv_find_binary_search(valid_s390_opts, ^~~~~~~~~~~~~~~ ../src/libnm-glib-aux/nm-shared-utils.h:2033:60: note: expanded from macro 'nm_utils_strv_find_binary_search' const char *const *const _strv = NM_CAST_STRV_CC(strv); \ ^ ../src/libnm-glib-aux/nm-macros-internal.h:706:21: note: expanded from macro 'NM_CAST_STRV_CC' (_Generic ((value), \ ^ --- configure.ac | 2 +- meson.build | 14 ++++++++++---- src/libnm-glib-aux/nm-macros-internal.h | 9 ++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index de6e272360..fe0568afe6 100644 --- a/configure.ac +++ b/configure.ac @@ -1177,7 +1177,7 @@ if test -n "$sanitizers"; then fi AC_MSG_CHECKING([CC support C11 _Generic()]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; }]], +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo(void); static const char *const buf[1] = { "a" }; int foo() { int a = 0; int b = _Generic (a, int: 4) + _Generic(buf, const char *const*: 5); return b + a; }]], [[foo();]])], [cc_support_generic=1], [cc_support_generic=0]) diff --git a/meson.build b/meson.build index 7e2bf7ee93..f24718b052 100644 --- a/meson.build +++ b/meson.build @@ -785,11 +785,17 @@ config_h.set('NM_MORE_ASSERTS', more_asserts) more_logging = get_option('more_logging') config_h.set10('NM_MORE_LOGGING', more_logging) -generic_support_src = 'int main() { int a = 0; int b = _Generic (a, int: 4); return b + a; };' -config_h.set10('_NM_CC_SUPPORT_GENERIC', cc.compiles(generic_support_src)) +config_h.set10('_NM_CC_SUPPORT_GENERIC', + cc.compiles( + 'int foo(void); static const char *const buf[1] = { "a" }; int foo() { int a = 0; int b = _Generic (a, int: 4) + _Generic(buf, const char *const*: 5); return b + a; }' + ) +) -auto_support_src = 'int main() { int a = 0; __auto_type b = a; return b + a; };' -config_h.set10('_NM_CC_SUPPORT_AUTO_TYPE', cc.compiles(auto_support_src)) +config_h.set10('_NM_CC_SUPPORT_AUTO_TYPE', + cc.compiles( + 'int main() { int a = 0; __auto_type b = a; return b + a; };' + ) +) # Vala bindings vapi_opt = get_option('vapi') diff --git a/src/libnm-glib-aux/nm-macros-internal.h b/src/libnm-glib-aux/nm-macros-internal.h index ce89e235c1..d31599f630 100644 --- a/src/libnm-glib-aux/nm-macros-internal.h +++ b/src/libnm-glib-aux/nm-macros-internal.h @@ -522,9 +522,12 @@ NM_G_ERROR_MSG(GError *error) /* In the meantime, NetworkManager requires C11 and _Generic() should always be available. * However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet * bump the C standard requirement. Leave this for the moment, but eventually we can - * drop it. */ - #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) \ - || (defined(__clang__)) + * drop it. + * + * Technically, gcc 4.9 already has some support for _Generic(). But there seems + * to be issues with propagating "const char *[5]" to "const char **". Only assume + * we have _Generic() since gcc 5. */ + #if (defined(__GNUC__) && __GNUC__ >= 5) || (defined(__clang__)) #define _NM_CC_SUPPORT_GENERIC 1 #else #define _NM_CC_SUPPORT_GENERIC 0