From e1efd2a2d7518c05c78dd870999201582b1e0fc7 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 14 Apr 2022 15:00:42 +0200 Subject: [PATCH] BUILD: sched: workaround crazy and dangerous warning in Clang 14 Ilya reported in issue #1638 that Clang 14 has invented a new warning that encourages to modify the code in a way that is not always equivalent, by turning "|" to "||" between some logical operators, except that the first one guarantees that all members of the expression will always be evaluated while the latter will stop at the first one which is true! This warning triggers in thread_has_tasks(), which is not sensitive to such change of behavior but which is built this way because it results in branchless code for something that most often evaluates to false for all terms. As such it was out of question to turn this to less efficient compare-and-jump that needlessly pollute the branch predictor, so the workaround consists in casting each expression to (int). It was verified that the code is the same. Yet another example of how-to-introduce-bugs-by-fixing-valid-code through warnings invented around a beer without thinking longer! This may need to be backported to a few older branches in case this compiler lands in recent distros or if gcc finds it wise to imitate it. --- include/haproxy/task.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/haproxy/task.h b/include/haproxy/task.h index c73df7c92..6bd1272b0 100644 --- a/include/haproxy/task.h +++ b/include/haproxy/task.h @@ -187,10 +187,10 @@ static inline int task_in_wq(struct task *t) /* returns true if the current thread has some work to do */ static inline int thread_has_tasks(void) { - return (!!(global_tasks_mask & tid_bit) | - !eb_is_empty(&th_ctx->rqueue) | - !!th_ctx->tl_class_mask | - !MT_LIST_ISEMPTY(&th_ctx->shared_tasklet_list)); + return ((int)!!(global_tasks_mask & tid_bit) | + (int)!eb_is_empty(&th_ctx->rqueue) | + (int)!!th_ctx->tl_class_mask | + (int)!MT_LIST_ISEMPTY(&th_ctx->shared_tasklet_list)); } /* puts the task in run queue with reason flags , and returns */