From nobody Wed Feb 11 20:55:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A1CFC7EE21 for ; Thu, 4 May 2023 21:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230346AbjEDVBf (ORCPT ); Thu, 4 May 2023 17:01:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229731AbjEDVBP (ORCPT ); Thu, 4 May 2023 17:01:15 -0400 Received: from smtpout.efficios.com (unknown [IPv6:2607:5300:203:b2ee::31e5]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C737D13290 for ; Thu, 4 May 2023 14:00:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1683230733; bh=ejcZRhDyFKbQO0Pq2uphS/at1qd6mS5DdbQdmXOnDzQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RtnX8wDZcF6Jl+yg7Dd9MSRqmNfuJYg1Un9qlf5XhMvxdr7G3SPJ/NC7b1o0U9QqO xNNKCrM3RFPuHBRWMX+pbAOtU94c/g8K1MJU0el1F3YlFSF7/SjANB97oUp1US8g0J UxTEkVNVZwlmjmGS1aBGe9SsZ3VpWXSKRUvWu3Lqq9qoURob4coNjaJISbSgUX1s3j Anak7Axro4o4SYd8WD2cOd+aVuCq5K+uK3qdUX0vVv9SSVXEkiSt7D5CUPNO1DMv+2 oGikVrgtWGdvksFhIcg3vSW6JI7vKEVlBfKdpSWREnRpNFOL6qvBmK1E8wORIWPnLu TE7ZR+jxlRkEg== Received: from localhost.localdomain (192-222-143-198.qc.cable.ebox.net [192.222.143.198]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4QC4Yn0vBhz122d; Thu, 4 May 2023 16:05:33 -0400 (EDT) From: Mathieu Desnoyers To: Andrew Morton Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , Greg Kroah-Hartman , Andy Shevchenko , David Howells , Ricardo Martinez Subject: [RFC PATCH 05/13] list.h: Fix parentheses around macro pointer parameter use Date: Thu, 4 May 2023 16:05:19 -0400 Message-Id: <20230504200527.1935944-6-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230504200527.1935944-1-mathieu.desnoyers@efficios.com> References: <20230504200527.1935944-1-mathieu.desnoyers@efficios.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add missing parentheses around use of macro argument "pos" in those patterns to ensure operator precedence behaves as expected: - typeof(*pos) - pos->member - "x =3D y" is changed for "x =3D (y)", because "y" can be an expression containing a comma if it is the result of the expansion of a macro such as #define eval(...) __VA_ARGS__, which would cause unexpected operator precedence. This use-case is far-fetched, but we have to choose one way or the other (with or without parentheses) for consistency, - x && y is changed for (x) && (y). Remove useless parentheses around use of macro parameter (head) in the following pattern: - list_is_head(pos, (head)) Because comma is the lowest priority operator already, so the extra pair of parentheses is redundant. This corrects the following usage pattern where operator precedence is unexpected: LIST_HEAD(testlist); struct test { struct list_head node; int a; }; // pos->member issue void f(void) { struct test *t1; struct test **t2 =3D &t1; list_for_each_entry((*t2), &testlist, node) { /* works */ //... } list_for_each_entry(*t2, &testlist, node) { /* broken */ //... } } // typeof(*pos) issue void f2(void) { struct test *t1 =3D NULL, *t2; t2 =3D list_prepare_entry((0 + t1), &testlist, node); /* work= s */ t2 =3D list_prepare_entry(0 + t1, &testlist, node); /* brok= en */ } Note that the macros in which "pos" is also used as an lvalue probably don't suffer from the lack of parentheses around "pos" in typeof(*pos), but add those nevertheless to keep everything consistent. Signed-off-by: Mathieu Desnoyers Cc: Andrew Morton Cc: Greg Kroah-Hartman Cc: Andy Shevchenko Cc: David Howells Cc: Ricardo Martinez --- include/linux/list.h | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/include/linux/list.h b/include/linux/list.h index f10344dbad4d..d197b1a6f411 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -603,7 +603,7 @@ static inline void list_splice_tail_init(struct list_he= ad *list, * @head: the head for your list. */ #define list_for_each(pos, head) \ - for (pos =3D (head)->next; !list_is_head(pos, (head)); pos =3D pos->next) + for (pos =3D (head)->next; !list_is_head(pos, head); pos =3D (pos)->next) =20 /** * list_for_each_rcu - Iterate over a list in an RCU-safe fashion @@ -612,8 +612,8 @@ static inline void list_splice_tail_init(struct list_he= ad *list, */ #define list_for_each_rcu(pos, head) \ for (pos =3D rcu_dereference((head)->next); \ - !list_is_head(pos, (head)); \ - pos =3D rcu_dereference(pos->next)) + !list_is_head(pos, head); \ + pos =3D rcu_dereference((pos)->next)) =20 /** * list_for_each_continue - continue iteration over a list @@ -623,7 +623,7 @@ static inline void list_splice_tail_init(struct list_he= ad *list, * Continue to iterate over a list, continuing after the current position. */ #define list_for_each_continue(pos, head) \ - for (pos =3D pos->next; !list_is_head(pos, (head)); pos =3D pos->next) + for (pos =3D (pos)->next; !list_is_head(pos, head); pos =3D (pos)->next) =20 /** * list_for_each_prev - iterate over a list backwards @@ -631,7 +631,7 @@ static inline void list_splice_tail_init(struct list_he= ad *list, * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ - for (pos =3D (head)->prev; !list_is_head(pos, (head)); pos =3D pos->prev) + for (pos =3D (head)->prev; !list_is_head(pos, head); pos =3D (pos)->prev) =20 /** * list_for_each_safe - iterate over a list safe against removal of list e= ntry @@ -640,9 +640,9 @@ static inline void list_splice_tail_init(struct list_he= ad *list, * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ - for (pos =3D (head)->next, n =3D pos->next; \ - !list_is_head(pos, (head)); \ - pos =3D n, n =3D pos->next) + for (pos =3D (head)->next, n =3D (pos)->next; \ + !list_is_head(pos, head); \ + pos =3D (n), n =3D (pos)->next) =20 /** * list_for_each_prev_safe - iterate over a list backwards safe against re= moval of list entry @@ -651,9 +651,9 @@ static inline void list_splice_tail_init(struct list_he= ad *list, * @head: the head for your list. */ #define list_for_each_prev_safe(pos, n, head) \ - for (pos =3D (head)->prev, n =3D pos->prev; \ - !list_is_head(pos, (head)); \ - pos =3D n, n =3D pos->prev) + for (pos =3D (head)->prev, n =3D (pos)->prev; \ + !list_is_head(pos, head); \ + pos =3D (n), n =3D (pos)->prev) =20 /** * list_count_nodes - count nodes in the list @@ -677,7 +677,7 @@ static inline size_t list_count_nodes(struct list_head = *head) * @member: the name of the list_head within the struct. */ #define list_entry_is_head(pos, head, member) \ - (&pos->member =3D=3D (head)) + (&(pos)->member =3D=3D (head)) =20 /** * list_for_each_entry - iterate over list of given type @@ -686,7 +686,7 @@ static inline size_t list_count_nodes(struct list_head = *head) * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ - for (pos =3D list_first_entry(head, typeof(*pos), member); \ + for (pos =3D list_first_entry(head, typeof(*(pos)), member); \ !list_entry_is_head(pos, head, member); \ pos =3D list_next_entry(pos, member)) =20 @@ -697,7 +697,7 @@ static inline size_t list_count_nodes(struct list_head = *head) * @member: the name of the list_head within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ - for (pos =3D list_last_entry(head, typeof(*pos), member); \ + for (pos =3D list_last_entry(head, typeof(*(pos)), member); \ !list_entry_is_head(pos, head, member); \ pos =3D list_prev_entry(pos, member)) =20 @@ -710,7 +710,7 @@ static inline size_t list_count_nodes(struct list_head = *head) * Prepares a pos entry for use as a start point in list_for_each_entry_co= ntinue(). */ #define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) + ((pos) ? : list_entry(head, typeof(*(pos)), member)) =20 /** * list_for_each_entry_continue - continue iteration over list of given ty= pe @@ -773,10 +773,10 @@ static inline size_t list_count_nodes(struct list_hea= d *head) * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ - for (pos =3D list_first_entry(head, typeof(*pos), member), \ + for (pos =3D list_first_entry(head, typeof(*(pos)), member), \ n =3D list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ - pos =3D n, n =3D list_next_entry(n, member)) + pos =3D (n), n =3D list_next_entry(n, member)) =20 /** * list_for_each_entry_safe_continue - continue list iteration safe agains= t removal @@ -792,7 +792,7 @@ static inline size_t list_count_nodes(struct list_head = *head) for (pos =3D list_next_entry(pos, member), \ n =3D list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ - pos =3D n, n =3D list_next_entry(n, member)) + pos =3D (n), n =3D list_next_entry(n, member)) =20 /** * list_for_each_entry_safe_from - iterate over list from current point sa= fe against removal @@ -807,7 +807,7 @@ static inline size_t list_count_nodes(struct list_head = *head) #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n =3D list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ - pos =3D n, n =3D list_next_entry(n, member)) + pos =3D (n), n =3D list_next_entry(n, member)) =20 /** * list_for_each_entry_safe_reverse - iterate backwards over list safe aga= inst removal @@ -820,10 +820,10 @@ static inline size_t list_count_nodes(struct list_hea= d *head) * of list entry. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos =3D list_last_entry(head, typeof(*pos), member), \ + for (pos =3D list_last_entry(head, typeof(*(pos)), member), \ n =3D list_prev_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ - pos =3D n, n =3D list_prev_entry(n, member)) + pos =3D (n), n =3D list_prev_entry(n, member)) =20 /** * list_safe_reset_next - reset a stale list_for_each_entry_safe loop @@ -1033,11 +1033,11 @@ static inline void hlist_move_list(struct hlist_hea= d *old, #define hlist_entry(ptr, type, member) container_of(ptr,type,member) =20 #define hlist_for_each(pos, head) \ - for (pos =3D (head)->first; pos ; pos =3D pos->next) + for (pos =3D (head)->first; pos ; pos =3D (pos)->next) =20 #define hlist_for_each_safe(pos, n, head) \ - for (pos =3D (head)->first; pos && ({ n =3D pos->next; 1; }); \ - pos =3D n) + for (pos =3D (head)->first; (pos) && ({ n =3D (pos)->next; 1; }); \ + pos =3D (n)) =20 #define hlist_entry_safe(ptr, type, member) \ ({ typeof(ptr) ____ptr =3D (ptr); \ @@ -1082,8 +1082,8 @@ static inline void hlist_move_list(struct hlist_head = *old, * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_safe(pos, n, head, member) \ - for (pos =3D hlist_entry_safe((head)->first, typeof(*pos), member);\ - pos && ({ n =3D pos->member.next; 1; }); \ - pos =3D hlist_entry_safe(n, typeof(*pos), member)) + for (pos =3D hlist_entry_safe((head)->first, typeof(*(pos)), member);\ + (pos) && ({ n =3D (pos)->member.next; 1; }); \ + pos =3D hlist_entry_safe(n, typeof(*(pos)), member)) =20 #endif --=20 2.25.1