LLD 13 adds -z start-stop-gc and makes it the default, resulting in:
CCLD src/core/NetworkManager-all-sym
ld.lld: error: undefined symbol: __stop_connection_defaults
>>> referenced by nm-config.c:0 (src/core/nm-config.c:0)
>>> libNetworkManager_la-nm-config.o:(read_config) in archive src/core/.libs/libNetworkManager.a
>>> referenced by nm-config-data.c:1598 (src/core/nm-config-data.c:1598)
>>> libNetworkManager_la-nm-config-data.o:(nm_config_data_get_connection_default) in archive src/core/.libs/libNetworkManager.a
>>> referenced by nm-config-data.c:0 (src/core/nm-config-data.c:0)
>>> libNetworkManager_la-nm-config-data.o:(nm_config_data_get_connection_default) in archive src/core/.libs/libNetworkManager.a
ld.lld: error: undefined symbol: __start_connection_defaults
>>> referenced by nm-config.c:0 (src/core/nm-config.c:0)
>>> libNetworkManager_la-nm-config.o:(read_config) in archive src/core/.libs/libNetworkManager.a
>>> referenced by nm-config.c:0 (src/core/nm-config.c:0)
>>> libNetworkManager_la-nm-config.o:(read_config) in archive src/core/.libs/libNetworkManager.a
>>> referenced by nm-config.c:0 (src/core/nm-config.c:0)
>>> libNetworkManager_la-nm-config.o:(read_config) in archive src/core/.libs/libNetworkManager.a
>>> referenced 2 more times
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Add __attribute__((__retain__)) to prevent GC of the connection
defaults.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1008
We use the cleanup attribute heavily. It's useful for deferring
deallocation. For example, we have code like:
gs_unref_object NMBluezManager *self_keep_alive = g_object_ref(self);
where we don't use the variable otherwise, except for owning (and
freeing) the reference. This already lead to a compiler warning about
unused variable, which we would workaround with
_nm_unused gs_unref_object NMBluezManager *self_keep_alive = g_object_ref(self);
With clang 13.0.0~rc1-1.fc35, this got worse. Now for example also
static inline void
nm_strvarray_set_strv(GArray **array, const char *const *strv)
{
gs_unref_array GArray *array_old = NULL;
array_old = g_steal_pointer(array);
if (!strv || !strv[0])
return;
nm_strvarray_ensure(array);
for (; strv[0]; strv++)
nm_strvarray_add(*array, strv[0]);
}
leads to a warning
./src/libnm-glib-aux/nm-shared-utils.h:3078:28: error: variable array_old set but not used [-Werror,-Wunused-but-set-variable]
gs_unref_array GArray *array_old = NULL;
^
This is really annoying. We don't want to plaster our code with _nm_unused,
because that might hide actual issues. But we also want to keep using this
pattern and need to avoid the warning.
A problem is also that GCC usually does not warn about truly unused
variables with cleanup attribute. Clang was very useful here to flag
such variables. But now clang warns about cases which are no bugs, which
is a problem. So this does loose some useful warnings. On the other hand,
a truly unused variable (with cleanup attribute) is ugly, but not an actual
problem.
Now, with clang 13, automatically mark nm_auto() variables as _nm_unused
as workaround.
We have a copy of a few linux user space headers in `src/linux-headers`.
The idea is that we want to use recent kernel API, and not depend on the
kernel UAPI headers installed on the build system (and not need to
workaround that).
However, we may not be able to simply compile them, because they too
have dependencies. For example,
../src/linux-headers/ethtool.h:1389:2: error: implicit declaration of function '__KERNEL_DIV_ROUND_UP' [-Werror=implicit-function-declaration]
__u32 queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)];
^
As workaround, don't include headers from "linux-headers" directly,
but only include the new "libnm-std-aux/nm-linux-compat.h" adapter
header, which tries to solve these incompatibilities.
Fixes: 34d48d2596 ('platform: clear all BASE types when setting advertised modes for ethernet autoneg')
The formatting produced by clang-format depends on the version of the
tool. The version that we use is the one of the current Fedora release.
Fedora 34 recently updated clang (and clang-tools-extra) from version
12.0.0 to 12.0.1. This brings some changes.
Update the formatting.
Like nm_utils_addr_family_to_char(), but gives a different treatment to
AF_UNSPEC to return "" instead of 'X'. As such, it also needs to
return a string and not a char.
We use NM_PTRARRAY_LEN(), and I find it a bit ugly that a macro does so
much. Maybe, it's better to have it as a function.
But the macro currently lives in "libnm-std-aux/nm-std-aux.h", which
is header-only. To add it to a C source file, we would have to move
it to another header, but "libnm-std-aux/nm-std-aux.h" is nice because
it gets included by default already.
Keep it in "libnm-std-aux/nm-std-aux.h", but implement it as an inline
function.
The macro now only does (as before) some type checking shenanigans to ensure
that the argument is a pointer to pointers.
In practice, there is probably very little difference compared to
the macro before, likely the code will anyway be inlined.
Replace NM_STATIC_ASSERT_EXPR() by NM_STATIC_ASSERT_EXPR_1() and
NM_STATIC_ASSERT_EXPR_VOID(). NM_STATIC_ASSERT_EXPR_VOID() can be
used as an expression that returns void (that is, a simple statement).
On the other hand, NM_STATIC_ASSERT_EXPR_1() itself retuns
a compile time constant of int value 1. The latter is useful, because
we can use the 1 to combine static assertions in expressions that
are themself compile time constants, like
#define STATIC_CHECK_AND_GET(cond, value) \
(NM_STATIC_ASSERT_EXPR_1(cond) ? (value) : (value))
This is itself a compile time constant if value is a compile
time constant. Also, it does the compile time check that "cond"
is true.
We have variadic macros like NM_UTILS_ENUM2STR() that create a switch
statement. Their implementation relies on the way how __VA_ARGS__
gets expanded to a comma separated list. But that implementation is
not great. Let's instead add (and later use) NM_VA_ARGS_JOIN() which
can join variadic arguments by a configurable separator.
Some compiler versions don't like to dereference and opaque
pointer for typeof:
gcc 8.3.1-5.1.el8 on RHEL:
In file included from ./src/libnm-glib-aux/nm-macros-internal.h:41,
from ./src/libnm-glib-aux/nm-default-glib.h:68,
from ./src/libnm-glib-aux/nm-default-glib-i18n-lib.h:13,
from ./src/libnm-core-impl/nm-default-libnm-core.h:11,
from src/libnm-core-impl/nm-setting-8021x.c:7:
src/libnm-core-impl/nm-setting-8021x.c: In function '_nm_setting_802_1x_cert_value_to_bytes':
./src/libnm-glib-aux/nm-glib.h:417:16: error: dereferencing pointer to incomplete type 'GBytes' {aka 'struct _GBytes'}
typeof(**_pp) *const _p = *_pp; \
^~~~~
src/libnm-core-impl/nm-setting-8021x.c:361:12: note: in expansion of macro 'g_steal_pointer'
return g_steal_pointer(&bytes);
^~~~~~~~~~~~~~~
./src/libnm-glib-aux/nm-glib.h:417:54: error: initialization of 'int * const' from incompatible pointer type 'GBytes *' {aka 'struct _GBytes *'} [-Werror=incompatible-pointer-types]
typeof(**_pp) *const _p = *_pp; \
^
src/libnm-core-impl/nm-setting-8021x.c:361:12: note: in expansion of macro 'g_steal_pointer'
return g_steal_pointer(&bytes);
^~~~~~~~~~~~~~~
./src/libnm-glib-aux/nm-glib.h:415:6: error: returning 'int * const' from a function with incompatible return type 'GBytes *' {aka 'struct _GBytes *'} [-Werror=incompatible-pointer-types]
({ \
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typeof(*(pp)) *const _pp = (pp); \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typeof(**_pp) *const _p = *_pp; \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_nm_unused const void *const _p_type_check = _p; \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\
~
*_pp = NULL; \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_p; \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
})
~~
src/libnm-core-impl/nm-setting-8021x.c:361:12: note: in expansion of macro 'g_steal_pointer'
return g_steal_pointer(&bytes);
^~~~~~~~~~~~~~~
Fixes: 5bc511203e ('all: make nm_steal_pointer() and g_steal_pointer() more typesafe using typeof()')
The previous code would always cast the argument to "void *", and thus
loose some type information.
For example,
gulong variable = 0;
g_steal_pointer(&variable);
would compile, when it shouldn't.
In general, we try to avoid redefining glib macros and headers. But we
really want those extra compile time checks that we can get, so let's do
it.
Originally, we would define G_LOG_DOMAIN via CFLAGS arguments.
Since commit 341b6e0704 ('all: change G_LOG_DOMAIN to "nm"') we would
instead set it in source and uniformly define it as "nm".
The reasons are that most parts of our source should not use g_log() directly,
and there is an aim to avoid special CFLAGS to simplify the build setup.
However, dispatcher indeed uses g_log() for logging, so the value there
is important.
Fix that, but this time by setting the define in source not via
CFLAGS.
Fixes: 341b6e0704 ('all: change G_LOG_DOMAIN to "nm"')