glib-aux: rework NM_HASH_COMBINE_BOOLS() macro to avoid expression statement

clang 3.4.2-9.el7 dislikes expressions in the form

    int v;
    struct {
        typeof(({ v; })) _field;
    } x;

    error: statement expression not allowed at file scope
    typeof( ({ v; }) ) _field;
            ^

That is, if the argument to typeof() is an expression statement. But this is
what

    nm_hash_update_val(&h, ..., NM_HASH_COMBINE_BOOLS(...))

expands to. Rework NM_HASH_COMBINE_BOOLS() to avoid the expression statement.

We still have the static assertion for the size of the return type.
We no longer have the _nm_hash_combine_bools_type typedef. It really
wasn't needed, and the current variant is always safe without it.

Fixes: 23adeed244 ('glib-aux: use NM_VA_ARGS_FOREACH() to implement NM_HASH_COMBINE_BOOLS()')
This commit is contained in:
Thomas Haller 2021-06-22 22:50:13 +02:00
parent 1e29a7e66b
commit 895b7dd95a
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 7 additions and 11 deletions

View file

@ -508,6 +508,8 @@ test_nm_hash(void)
g_assert(((typeof(x)) -1) > 0);
}
#endif
NM_STATIC_ASSERT_EXPR_VOID(NM_HASH_COMBINE_BOOLS(int, 1, 0, 1) == 5);
}
/*****************************************************************************/

View file

@ -122,18 +122,12 @@ nm_hash_update_bool(NMHashState *state, bool val)
nm_hash_update(state, &val, sizeof(val));
}
#define _NM_HASH_COMBINE_BOOLS_OP(x, n) \
((x) ? ((_nm_hash_combine_bools_type) NM_BIT((n))) : ((_nm_hash_combine_bools_type) 0))
#define _NM_HASH_COMBINE_BOOLS_OP(x, n) ((x) ? NM_BIT((n)) : 0u)
#define NM_HASH_COMBINE_BOOLS(type, ...) \
({ \
typedef type _nm_hash_combine_bools_type; \
\
G_STATIC_ASSERT(NM_NARG(__VA_ARGS__) <= 8 * sizeof(_nm_hash_combine_bools_type)); \
\
(_nm_hash_combine_bools_type)( \
NM_VA_ARGS_FOREACH(, , |, _NM_HASH_COMBINE_BOOLS_OP, __VA_ARGS__)); \
})
#define NM_HASH_COMBINE_BOOLS(type, ...) \
((type) (NM_STATIC_ASSERT_EXPR_1(NM_NARG(__VA_ARGS__) <= 8 * sizeof(type)) \
? (NM_VA_ARGS_FOREACH(, , |, _NM_HASH_COMBINE_BOOLS_OP, __VA_ARGS__)) \
: 0))
#define nm_hash_update_bools(state, ...) \
nm_hash_update_val(state, NM_HASH_COMBINE_BOOLS(guint8, __VA_ARGS__))