selftests/bpf: Fix "expression result unused" warnings with icecc
authorIlya Leoshkevich <iii@linux.ibm.com>
Fri, 29 Aug 2025 02:53:57 +0000 (04:53 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 9 Sep 2025 22:07:58 +0000 (15:07 -0700)
icecc is a compiler wrapper that distributes compile jobs over a build
farm [1]. It works by sending toolchain binaries and preprocessed
source code to remote machines.

Unfortunately using it with BPF selftests causes build failures due to
a clang bug [2]. The problem is that clang suppresses the
-Wunused-value warning if the unused expression comes from a macro
expansion. Since icecc compiles preprocessed source code, this
information is not available. This leads to -Wunused-value false
positives.

obj_new_no_struct() and obj_new_acq() use the bpf_obj_new() macro and
discard the result. arena_spin_lock_slowpath() uses two macros that
produce values and ignores the results. Add (void) casts to explicitly
indicate that this is intentional and suppress the warning.

An alternative solution is to change the macros to not produce values.
This would work today for the arena_spin_lock_slowpath() issue, but in
the future there may appear users who need them. Another potential
solution is to replace these macros with functions. Unfortunately this
would not work, because these macros work with unknown types and
control flow.

[1] https://github.com/icecc/icecream
[2] https://github.com/llvm/llvm-project/issues/142614

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20250829030017.102615-2-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h
tools/testing/selftests/bpf/progs/linked_list_fail.c

index d67466c1ff77540160d9e50bc383a78569f452f9..f90531cf3ee59edfe83404e3758653c2f36af1de 100644 (file)
@@ -302,7 +302,7 @@ int arena_spin_lock_slowpath(arena_spinlock_t __arena __arg_arena *lock, u32 val
         * barriers.
         */
        if (val & _Q_LOCKED_MASK)
-               smp_cond_load_acquire_label(&lock->locked, !VAL, release_err);
+               (void)smp_cond_load_acquire_label(&lock->locked, !VAL, release_err);
 
        /*
         * take ownership and clear the pending bit.
@@ -380,7 +380,7 @@ queue:
                /* Link @node into the waitqueue. */
                WRITE_ONCE(prev->next, node);
 
-               arch_mcs_spin_lock_contended_label(&node->locked, release_node_err);
+               (void)arch_mcs_spin_lock_contended_label(&node->locked, release_node_err);
 
                /*
                 * While waiting for the MCS lock, the next pointer may have
index 6438982b928bdcb2efb3fea6289ccae60fb2c080..ddd26d1a083f725d827610c3a926cd1dc8ff964d 100644 (file)
@@ -226,8 +226,7 @@ int obj_new_no_composite(void *ctx)
 SEC("?tc")
 int obj_new_no_struct(void *ctx)
 {
-
-       bpf_obj_new(union { int data; unsigned udata; });
+       (void)bpf_obj_new(union { int data; unsigned udata; });
        return 0;
 }
 
@@ -252,7 +251,7 @@ int new_null_ret(void *ctx)
 SEC("?tc")
 int obj_new_acq(void *ctx)
 {
-       bpf_obj_new(struct foo);
+       (void)bpf_obj_new(struct foo);
        return 0;
 }