Commit graph

71 commits

Author SHA1 Message Date
Thomas Haller
d3548279c1
std-aux: suppress verbose assert message with _nm_assert_fail()
We also do that with g_return*() macros. These strings increase the
binary size for little use. Drop them, unless we build with
more asserts enabled.

This affects nm_assert() messages.
2023-02-13 09:33:10 +01:00
Thomas Haller
a29eb970c8
Revert "std-aux: drop assertion and function name from assert() in release mode"
glibc defines __assert_fail as:

  extern void __assert_fail (const char *__assertion, const char *__file,
                             unsigned int __line, const char *__function)
       __THROW __attribute__ ((__noreturn__));

but musl as:

  _Noreturn void __assert_fail (const char *, const char *, int, const char *);

(note the difference in the type for the line argument).

This cannot be made to work, unless we would detect the used type at configure
time, which seems too much effort.

Drop this again.

This reverts commit 1ce29e120b.

Fixes: 1ce29e120b ('std-aux: drop assertion and function name from assert() in release mode')
2023-02-13 08:46:40 +01:00
Thomas Haller
2b89b2dc01
std-aux: add _NM_PTR_IS_ALIGNED() helper macro 2022-12-16 10:53:23 +01:00
Thomas Haller
63b34ac78a
std-aux: allow nesting of NM_CAST_ALIGN() macros
To support:

    return NM_CAST_ALIGN(const NMPObject,
                         nm_dedup_multi_obj_ref(NM_CAST_ALIGN(const NMDedupMultiObj, obj)));
2022-12-14 09:40:02 +01:00
Thomas Haller
4ecd25a139
std-aux: add NM_CAST_ALIGN() helper 2022-12-09 09:15:55 +01:00
Thomas Haller
4753358dd5
std-aux: mark failures of nm_assert() as unreachable code
- with nm_assert(), if the argument is a compile time constant
  always check it (regardless of NDEBUG, G_DISABLE_ASSERT)
  and mark the failure as _nm_unreachable_code(). We do this,
  even if we usually would not evaluate run time checks with
  NDEBUG/G_DISABLE_ASSERT.

- with nm_assert_se(), if assertions are disabled with NDEBUG
  and G_DISABLE_ASSERT, still mark the path as _nm_unreachable_code().
2022-12-06 17:03:04 +01:00
Thomas Haller
06931221b5
std-aux: mark _nm_assert_fail() as _nm_unreachable_code() with NDEBUG/G_DISABLE_ASSERT
This is useful, because it can avoid compiler warnings that are
emitted if the compiler things that the code can be reached.
_nm_assert_fail() can clearly never be reached (unless a bug happens).

When compiling we can disable assertion checks with
NDEBUG/G_DISABLE_ASSERT, but if we know that an assertion must not be
hit (for example with nm_assert_not_reached()) then we still want to
mark the path as unreachable, even if assert() does not abort the
process.
2022-12-06 17:03:04 +01:00
Thomas Haller
5ac5d7f8c3
std-aux: add _nm_unreachable_code() macro to wrap __builtin_unreachable()
This is a GCC-ism, but clang and all our current compiler support it.
2022-12-06 17:03:04 +01:00
Thomas Haller
fffdb14887
std-aux: make NM_BOOLEAN_EXPR() a constant expression for constant arguments
This allows the compiler to see that nm_assert(0) is unreachable code.
That is because nm_assert(0) calls NM_LIKELY(0), which calls
NM_BOOLEAN_EXPR(0). The latter was a statement expression, which
to the compiler was not a constant expression. Hence, this may trigger
compiler warnings about uninitialized variables.

Let NM_BOOLEAN_EXPR() to be constant, if the arguments are.

This can avoid compiler warnings in some cases.

Note that __builtin_choose_expr(__builtin_constant_p(...), ...) does
not properly work with gcc 4.8 ([1]). Hence only do macro shenanigans
with a newer gcc. Then entire point of NM_BOOLEAN_EXPR() is anyway
to preserve the "-Wparentheses" warning (while only evaluating the
argument once, being safe with nested invocations, propagate constness).
If we don't care about "-Wparentheses", it should be the same as
(!!(expr)). We can ignore that on non-recent gcc.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449
2022-12-06 17:03:03 +01:00
Thomas Haller
7483dfd7c4
std-aux: fix _NM_ASSERT_FAIL_ENABLED for plain assert() and NDEBUG
Fixes: 8e3299498d ('std-aux,glib-aux: rework nm_assert() implementations')
2022-12-06 17:02:37 +01:00
Thomas Haller
18e107e098
std-aux: implement static-asserts via bitfields
The implementation for static asserts with (sizeof(char[(cond) ? 1 : -1]))
silently fails if the condition is not a compile time constant, because
it results in a VLA which is evaluated at runtime. Well, for that reason
we build with "-Wvla" to catch accidentally using a non-const expression
in a static assert. But still, we can do better. Use instead bitfields
to trigger the compiler error. This works only with static expressions
and also without "-Wvla".

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1468
2022-11-23 18:02:38 +01:00
Thomas Haller
e7b1fd9dbc
std-aux: add code comment to NM_BOOLEAN_EXPR() 2022-11-04 09:27:37 +01:00
Beniamino Galvani
8bd72d5f2e std-aux: fix NM_LIKELY()/NM_UNLIKELY() macros
Fix this compile error when "defined(__GNUC__) && (__GNUC__ > 2) &&
defined(__OPTIMIZE__)" doesn't match:

  In file included from ../src/libnm-std-aux/nm-default-std.h:102,
                   from ../src/libnm-std-aux/nm-std-utils.c:3:
  ../src/libnm-std-aux/nm-std-aux.h: In function ‘NM_ALIGN_TO’:
  ../src/libnm-std-aux/nm-std-aux.h:160:6: error: expected expression before ‘{’ token
    160 |     ({                                 \
        |      ^
  ../src/libnm-std-aux/nm-std-aux.h:169:31: note: in expansion of macro ‘_NM_BOOLEAN_EXPR_IMPL’
    169 | #define NM_BOOLEAN_EXPR(expr) _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr)
        |                               ^~~~~~~~~~~~~~~~~~~~~
  ../src/libnm-std-aux/nm-std-aux.h:175:27: note: in expansion of macro ‘NM_BOOLEAN_EXPR’
    175 | #define NM_LIKELY(expr)   NM_BOOLEAN_EXPR(expr)
        |                           ^~~~~~~~~~~~~~~
  ../src/libnm-std-aux/nm-std-aux.h:238:19: note: in expansion of macro ‘NM_LIKELY’
    238 |         } else if NM_LIKELY (cond) {                                  \
        |                   ^~~~~~~~~
  ../src/libnm-std-aux/nm-std-aux.h:449:5: note: in expansion of macro ‘nm_assert’
    449 |     nm_assert(nm_utils_is_power_of_two(ali));
        |     ^~~~~~~~~

The NM_LIKELY()/NM_UNLIKELY() macros should be alwas called enclosed
in parentheses like in:

 if (NM_LIKELY(i == 1)) ...

and should be expanded with only a single pair of parentheses so that
expressions like (i = 1) generate a compiler warning.

Fixes: 030d68aef7 ('shared: add nm_assert() to "nm-std-aux.h"')
2022-11-04 09:12:04 +01:00
Thomas Haller
0ffe391f82
std-aux: fix build error due to __assert_fail() missing with NDEBUG
<assert.h> only defines __assert_fail() if NDEBUG is not on.
Fix that.

Fixes: 8e3299498d ('std-aux,glib-aux: rework nm_assert() implementations')
2022-10-29 21:43:33 +02:00
Thomas Haller
3254f33b33
std-aux: assert against any EBADF error in nm_close()
Previously, nm_close() accepted EBADF, as long as fd was negative.

Getting EBADF for a non-negative file descriptor is a serious bug,
because in multi threaded applications there is a race to close
an unrelated file descriptor. Also, it indicates that somebody
messed up the tracking of the resource, which indicates a bug.

Getting EBADF on a negative FD is less of a problem.
But it still indicates that the caller does something they likely
don't intend to.

Assert against any EBADF.

Note that nm_clear_fd() and nm_auto_close take already care to not
close negative "file descriptors". So, if you use those, you are
not affected.

If you want a close function that doesn't care about whether fd is set,
then maybe use `nm_clear_fd(&fd)` instead.
2022-10-25 13:12:48 +02:00
Thomas Haller
ad7d5887cd
all: cleanup close() handling and clarify nm_close()/nm_close_with_error()
Cleanup the handling of close().

First of all, closing an invalid (non-negative) file descriptor (EBADF) is
always a serious bug. We want to catch that. Hence, we should use nm_close()
(or nm_close_with_error()) which asserts against such bugs. Don't ever use
close() directly, to get that additional assertion.

Also, our nm_close() handles EINTR internally and correctly. Recent
POSIX defines that on EINTR the close should be retried. On Linux,
that is never correct. After close() returns, the file descriptor is
always closed (or invalid). nm_close() gets this right, and pretends
that EINTR is a success (without retrying).

The majority of our file descriptors are sockets, etc. That means,
often an error from close isn't something that we want to handle. Adjust
nm_close() to return no error and preserve the caller's errno. That is
the appropriate reaction to error (ignoring it) in most of our cases.

And error from close may mean that there was an IO error (except EINTR
and EBADF). In a few cases, we may want to handle that. For those
cases we have nm_close_with_error().

TL;DR: use almost always nm_close(). Unless you want to handle the error
code, then use nm_close_with_error(). Never use close() directly.

There is much reading on the internet about handling errors of close and
in particular EINTR. See the following links:

https://lwn.net/Articles/576478/
https://askcodes.net/coding/what-to-do-if-a-posix-close-call-fails-
https://www.austingroupbugs.net/view.php?id=529
https://sourceware.org/bugzilla/show_bug.cgi?id=14627
https://news.ycombinator.com/item?id=3363819
https://peps.python.org/pep-0475/
2022-10-25 13:12:48 +02:00
Thomas Haller
1ce29e120b
std-aux: drop assertion and function name from assert() in release mode
For g_assert() and g_return*() we already do the same, in
"src/libnm-glib-aux/nm-gassert-patch.h"

Also patch __assert_fail() so that it omits the condition text and the
function name in production builds.

Note that this is a bit ugly, for two reasons:

- again, we make assumptions that __assert_fail() exists. In practice,
  this is the case for glibc and musl.

- <assert.h> can be included multiple times, while also forward
  declaring __assert_fail(). That means, we cannot add a macro

  #define __assert_fail(...)

  because that would break the forward declaration. Instead,
  just `#define __assert_fail _nm_assert_fail_internal`

Of course, this only affects direct calls to assert(), which we have
few. nm_assert() is not affected, because that anyway doesn't do
anything, unless NM_MORE_ASSERTS is enabled.
2022-10-25 13:12:48 +02:00
Thomas Haller
8e3299498d
std-aux,glib-aux: rework nm_assert() implementations
1) ensure the compiler always sees the condition (even if
  it's unreachable). That is important, to avoid warnings
  about unused variables and to ensure the condition compiles.
  Previously, if NM_MORE_ASSERTS was enabled and NDEBUG (or
  G_DISABLE_ASSERT) was defined, the condition was not seen by
  the compiler.

2) to achieve point 1, we evaluate the expression now always in
  nm_assert() macro directly. This also has the benefit that we
  control exactly what is done there, and the implementation is
  guaranteed to not use any code that is not async-signal-safe
  (unless the assertion fails, of course).

3) add NM_MORE_ASSERTS_EFFECTIVE.
  When using no glib (libnm-std-aux), the assert is implemented
  by C89 assert(), while libnm-glib-aux redirects that to g_assert().
  Note that these assertions are only in effect, if both NM_MORE_ASSERTS
  and NDEBUG/G_DISABLE_ASSERT say so. NM_MORE_ASSERTS_EFFECTIVE
  is thus the effectively used level for nm_assert().

4) use the proper __assert_fail() and g_assertion_message_expr()
  calls. __assert_fail() is not standard, but it is there for glibc
  and musl. So relying on this is probably fine. Otherwise, we will
  get a compilation error and notice it.
2022-10-25 13:12:48 +02:00
Thomas Haller
197963fba3
std-aux: add _nm_noreturn macro 2022-10-25 13:12:48 +02:00
Thomas Haller
5f3259b620
std-aux: add NM_ALIGN*() macros
Taken from systemd's ALIGN(), ALIGN_TO(), etc.
2022-10-25 10:58:56 +02:00
Thomas Haller
263832a455
std-aux: add nm_memcpy() helper for handling copy of zero bytes 2022-10-24 08:48:05 +02:00
Thomas Haller
0920355227
std-aux: workaround unused variable with clang and nm_auto macro
It also can happen with clang 15 and clang 12. Just silence the warning.

The problem is of course, that we miss if a variable is really unused.
2022-10-20 21:15:56 +02:00
Thomas Haller
b28c6ca30e
all: avoid "-Wunreachable-code-generic-assoc" warning with _Generic()
Clang 15 ([1], [2]) added

  Added the -Wunreachable-code-generic-assoc diagnostic flag (grouped
  under the -Wunreachable-code flag) which is enabled by default and warns
  the user about _Generic selection associations which are unreachable
  because the type specified is an array type or a qualified type.

This causes compiler warnings with various uses of _Generic():

  ../src/libnm-glib-aux/nm-shared-utils.h:2489:12: error: due to lvalue conversion of the controlling expression, association of type 'const char *const *const' will never be selected becaus
  e it is qualified [-Werror,-Wunreachable-code-generic-assoc]
      return nm_strv_find_first((const char *const *) strv->pdata, strv->len, str);
             ^
  ../src/libnm-glib-aux/nm-shared-utils.h:475:25: note: expanded from macro 'nm_strv_find_first'
      _nm_strv_find_first(NM_CAST_STRV_CC(list), (len), (needle))
                          ^
  ../src/libnm-glib-aux/nm-macros-internal.h:397:22: note: expanded from macro 'NM_CAST_STRV_CC'
                 const char *const*const: (const char *const*) (value), \
                       ^

Clang is correct.

[1] https://releases.llvm.org/15.0.0/tools/clang/docs/ReleaseNotes.html#improvements-to-clang-s-diagnostics
[2] https://reviews.llvm.org/D125259
2022-10-11 17:21:11 +02:00
Thomas Haller
2f0808a610
std-aux: add _nm_always_inline for "__attribute__((__always_inline__))" 2022-10-11 08:59:48 +02:00
Thomas Haller
afcfbe9973
std-aux: workaround unused variable warning with clang 14 and nm_auto cleanup attribute 2022-10-07 20:57:44 +02:00
Thomas Haller
efcc030752
std-aux/trivial: fix typo in code comment 2022-09-28 13:30:45 +02:00
Thomas Haller
04a97e4e85
std-aux: workaround maybe uninitialized warning with LTO on nm_ip_addr_is_null()
LTO without assertion enabled, thinks that certain code paths
result in uninitialized code. Technically, it's not wrong, in practice
those are only in cases where we already failed an assertion.

  In function 'nm_ip_addr_is_null',
      inlined from 'canonicalize_ip_binary' at src/libnm-core-impl/nm-setting-ip-config.c:67:21,
      inlined from 'nm_ip_route_set_next_hop_binary' at src/libnm-core-impl/nm-setting-ip-config.c:1062:23:
  ./src/libnm-glib-aux/nm-inet-utils.h:80:12: error: 'a' may be used uninitialized [-Werror=maybe-uninitialized]
     80 |     return IN6_IS_ADDR_UNSPECIFIED(&a.addr6);
        |            ^
  src/libnm-core-impl/nm-setting-ip-config.c: In function 'nm_ip_route_set_next_hop_binary':
  ./src/libnm-glib-aux/nm-inet-utils.h:73:14: note: 'a' declared here
     73 |     NMIPAddr a;
        |              ^

Try to workaround that by letting nm_utils_addr_family_to_size() always
return a non-zero size. This is ugly, because in the assertion case fail
we might now also get an additional memory corruption that could have
been avoided by returning zero. However, it probably doesn't matter, because
in this scenario we are already in a bad situation.

Fixes: b02aeaf2f3 ('glib-aux: fix various nm_ip_addr_*() functions for unaligned addresses')
2022-08-25 21:15:38 +02:00
Thomas Haller
49ddb96d4e
std-aux: add nm_utils_addr_family_to_size_untrusted() helper 2022-08-09 08:02:36 +02:00
Thomas Haller
8153b3ff0c
std-aux: use unique local variable in NM_IN_SET() macro
If you do:

  nm_assert_addr_family(NMP_OBJECT_CAST_MPTCP_ADDR(obj)->addr_family));

then there are two nested NM_IN_SET() macro invocations. Once,
NMP_OBJECT_CAST_MPTCP_ADDR() checks that the object type is one of
a few selected (using NM_IN_SET()). Then, that is passed to
nm_assert_addr_family(), which checks NM_IN_SET(addr_family, AF_INET,
AF_INET6).

In general, it's easy to end up in a situation like this.

And it mostly works just fine. The only problem was that NM_IN_SET()
uses an internal, local variable "_x". The compiler will emit a very
verbose failure about the shadowed variable:

  ./src/libnm-std-aux/nm-std-aux.h:802:14: error: declaration of '_x' shadows a previous local [-Werror=shadow]
    802 |         type _x = (x);                                                \

NM_UNIQ_T() exists for this purpose. Use it. NM_IN_SET() is
popular enough to warrant a special treatment to avoid this pitfall.
2022-07-28 13:07:50 +02:00
Thomas Haller
6501f741fc
std-aux: add argument to "op" parameter for NM_VA_ARGS_FOREACH() macro
This will be needed to pass "NM_UNIQ" to the op macro, to construct
a NM_UNIQ_T() unique name.
2022-07-28 13:06:08 +02:00
Thomas Haller
5c54bad89d
std-aux: add nm_memeq() helper 2022-07-28 11:06:53 +02:00
Thomas Haller
c4992c75f7
std-aux: use nm_memcmp() in NM_CMP_DIRECT_MEMCMP()
NM_CMP_DIRECT_MEMCMP() gets called by NM_CMP_FIELD_MEMCMP_LEN().
For example, if you want to compare a NMIPAddr, it seems sensible
to call

  NM_CMP_FIELD_MEMCMP_LEN(obj1, obj2, addr, nm_utils_addr_family_to_size(obj1->addr_family));

Granted, nm_utils_addr_family_to_size() asserts that addr_family is
either AF_INET or AF_INET6. However, if the assertion fails, we don't
want yet another undefined behavior here and do the sensible thing
about n zero.

In general, for a low-level function that uses memcmp(), it's non
obvious to ensure that the caller does not accidentally invoke undefined
behavior. nm_memcmp() avoids that.
2022-07-20 10:15:28 +02:00
Thomas Haller
2ebc3ac7d9
std-aux: add nm_memcmp() helper 2022-07-20 10:15:23 +02:00
Thomas Haller
921af527f7
std-aux: cleanup NM_CMP_*() macros
- add code comments explaining some things.

- for NM_CMP_FIELD*() variants have a corresponding NM_CMP_DIRECT*()
  macro and use it (aside the "memcmp" variants, which don't translate
  directly).
2022-06-09 09:52:51 +02:00
Thomas Haller
f307e12080
std-aux: cast NM_IN_SET_SET() operands to "int" for "-Wbitwise-instead-of-logical" warning
Clang 14 has a new warning "-Wbitwise-instead-of-logical", and it warns
about our usage with NM_IN_SET_SE()/NM_IN_STRSET_SE(). It complains that we
are using '|' with boolean operands. Which is true (and intended), as we bitwise-or
the result of the '==' comparisons.

Work around the warning by casting the operands to "int". Note that
in C, the comparison operators have already a type "int", so this cast
should not result in any changes in the compiled code.

    ../src/libnm-core-impl/tests/test-general.c:9415:17: error: use of bitwise '|' with boolean operands [-Werror,-Wbitwise-instead-of-logical]
        _ASSERT(2, !NM_IN_SET_SE(-1, G(1), G(2)));
        ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../src/libnm-std-aux/nm-std-aux.h:800:30: note: expanded from macro 'NM_IN_SET_SE'
    #define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof(x), x, __VA_ARGS__)
                                 ^
    ../src/libnm-std-aux/nm-std-aux.h:789:39: note: expanded from macro '_NM_IN_SET'
            !!(NM_VA_ARGS_FOREACH(, , op, _NM_IN_SET_OP, __VA_ARGS__)); \
                                          ^
    ../src/libnm-std-aux/nm-std-aux.h:772:20: note: expanded from macro 'NM_VA_ARGS_FOREACH'
                       op,                                                   \
                       ^
    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
    ../src/libnm-glib-aux/nm-macros-internal.h:1603:47: note: expanded from macro '_G_BOOLEAN_EXPR'
    #define _G_BOOLEAN_EXPR(expr) NM_BOOLEAN_EXPR(expr)
                                  ~~~~~~~~~~~~~~~~^~~~~
    ../src/libnm-std-aux/nm-std-aux.h:167:62: note: expanded from macro 'NM_BOOLEAN_EXPR'
    #define NM_BOOLEAN_EXPR(expr) _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr)
                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
    ../src/libnm-std-aux/nm-std-aux.h:161:13: note: expanded from macro '_NM_BOOLEAN_EXPR_IMPL'
            if (expr)                      \
                ^~~~
    ../src/libnm-core-impl/tests/test-general.c:9415:17: note: cast one or both operands to int to silence this warning
    ../src/libnm-std-aux/nm-std-aux.h:800:30: note: expanded from macro 'NM_IN_SET_SE'
    #define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof(x), x, __VA_ARGS__)
                                 ^
    ../src/libnm-std-aux/nm-std-aux.h:789:39: note: expanded from macro '_NM_IN_SET'
            !!(NM_VA_ARGS_FOREACH(, , op, _NM_IN_SET_OP, __VA_ARGS__)); \
                                          ^
2022-03-16 00:57:17 +01:00
Thomas Haller
71f53d4069
std-aux: add code comment for NM_STR_HAS_PREFIX()/NM_STR_HAS_SUFFIX() 2022-03-09 09:10:45 +01:00
Harald van Dijk
58bfcffd59 core: support linking with LLD 13
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
2021-11-02 12:42:51 +01:00
Thomas Haller
1c85bc5ead
std-aux: work around "-Wunused-but-set-variable" warning with clang in nm_auto()
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.
2021-10-08 15:56:10 +02:00
Thomas Haller
a3ca768fbc
std-aux: minor cleanup in nm_steal_int() to compare number explicitly against zero 2021-10-06 17:55:11 +02:00
Thomas Haller
f3def63fed
std-aux: add nm_clear_fd() helper 2021-09-28 15:58:29 +02:00
Thomas Haller
37047aba36
std-aux: add nm_assert_addr_family_or_unspec() and nm_utils_addr_family_other() helpers 2021-09-28 12:56:39 +02:00
Thomas Haller
5e54cb5845
std-aux: let nm_assert() macros return a TRUE value
For most purposes, this makes no difference. But it allows
to write something like:

  if (   ptr
      && nm_assert(check_ptr(ptr))
      && other_check(ptr))
      ...
2021-08-31 16:34:02 +02:00
Thomas Haller
10e0c4261e
format: reformat code with clang-format-12.0.1-1.fc34
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.
2021-08-30 13:14:00 +02:00
Thomas Haller
1d789ca44b
std-aux: add XXX() macro 2021-08-11 14:17:24 +02:00
Thomas Haller
f9fa3fbf9f
std-aux: add nm_utils_addr_family_to_str() helper
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.
2021-08-05 14:59:09 +02:00
Thomas Haller
7459a8c67a
std-aux: use unique temporary variable in NM_IS_IPv4()
NM_IS_IPv4() should work well, also inside other macros and not
be concerned about shadowing another variable.
2021-08-05 14:59:01 +02:00
Thomas Haller
17f0acfdb3
std-aux: add _nm_nil macro
This is only useful to hack the clang-formatting.
2021-08-02 10:01:03 +02:00
Thomas Haller
3a6eb5920e
all: use _NM_ENSURE_POINTER() macro 2021-07-30 11:03:29 +02:00
Thomas Haller
4484363df0
std-aux: add _NM_ENSURE_POINTER() macro 2021-07-30 11:02:33 +02:00
Thomas Haller
387d5ded93
std-aux: move _NM_ENSURE_TYPE(), _NM_ENSURE_TYPE_CONST(), NM_STRUCT_OFFSET_ENSURE_TYPE() 2021-07-30 10:51:02 +02:00