Message ID | 20221224115657.kqyocti356cwm7hc@pengutronix.de |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp127474wrt; Sat, 24 Dec 2022 04:05:44 -0800 (PST) X-Google-Smtp-Source: AMrXdXtW59afpL/TmgoabTfyvNKt8bw881ZeYsbLOpVHN513K3nPaWH38kHthbStpwLE+jJb1glw X-Received: by 2002:a50:d659:0:b0:463:aeaf:338f with SMTP id c25-20020a50d659000000b00463aeaf338fmr11937689edj.32.1671883544530; Sat, 24 Dec 2022 04:05:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671883544; cv=none; d=google.com; s=arc-20160816; b=lM4JbZL6fvZl2wPc3Is/JFeg3k8ffaB5Z82N8PfOEOD8vMFuvXYXQuvdGYQP1RWFzd 6KxJiLamIKcLYQVJBOvxl27PhBkBHDuxzJt6vgezLd8WaoPBmzMXUC11gHDHt+MXwMDM +JFc9dhzcV8M5bCr7ehSCzBDph+Epqxh93Bfi37JMiuxGE5vvgDreO91VDpSGe5PcXML MutJwCcp8Qa5/f8PiYfl4+/YU/VnMb4iD1gcq2ylLgj2/Ukin+Dav3xQIziGTnUYnvhn nwxk/LYirSeDTnCtsQPDd+L3uP9vF2L+WQL9y3H4rKAI67zu8wrlNIIDfySOBI36wKY2 QfyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-disposition:mime-version:message-id :subject:cc:to:from:date; bh=1Z9YLR2JqLPQh2rckSBbLv4SFOL59xfWsVOORGPmx8k=; b=v/o9FjBPFr0SLj6HWAxinLnlxi43sqjHjhw4LXoRD/dl76Gv/pIHYO/KM8ErX9kgFY Y+p2WrR3oeEyuFxuZWNHATb+yjJWJK3ZHLNKWexyBtbnGmGxH7EuW5V4+Bb+QU4MYoGG js9tmoaBu8ljJnKjQayD1VPuw2v+hOwU2iQ/EBIUCd8IE8byd1BYIGTWYhziiyg2S1xU eO0qfs8wefMhPzcUF+ajEyhU7YAjrjaCHOOawJT4KqXuyNZOXfH7YKu+TwxxFIuUSL4l bTKbFARwmm8rVOeKFPswyVkB4cmOxQxlsK1JQDXFMwiJk6sUyASjUAirdktZJnF/tZB9 xDpQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y12-20020a056402270c00b0046c77f0b6bcsi5380383edd.562.2022.12.24.04.05.17; Sat, 24 Dec 2022 04:05:44 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230383AbiLXL5G (ORCPT <rfc822;pacteraone@gmail.com> + 99 others); Sat, 24 Dec 2022 06:57:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229570AbiLXL5F (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 24 Dec 2022 06:57:05 -0500 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CA3CDFE1 for <linux-kernel@vger.kernel.org>; Sat, 24 Dec 2022 03:57:03 -0800 (PST) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <ukl@pengutronix.de>) id 1p9399-0003j1-3j; Sat, 24 Dec 2022 12:56:59 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from <ukl@pengutronix.de>) id 1p9397-001QLS-P6; Sat, 24 Dec 2022 12:56:57 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from <ukl@pengutronix.de>) id 1p9397-007ZoX-4H; Sat, 24 Dec 2022 12:56:57 +0100 Date: Sat, 24 Dec 2022 12:56:57 +0100 From: Uwe =?utf-8?q?Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de> To: Julia Lawall <Julia.Lawall@inria.fr>, Nicolas Palix <nicolas.palix@imag.fr> Cc: cocci@inria.fr, linux-kernel@vger.kernel.org, kernel@pengutronix.de Subject: coccinelle: How to remove a return at the end of a void function? Message-ID: <20221224115657.kqyocti356cwm7hc@pengutronix.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="2doephs5xxov5shz" Content-Disposition: inline X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753096959379306537?= X-GMAIL-MSGID: =?utf-8?q?1753096959379306537?= |
Series |
coccinelle: How to remove a return at the end of a void function?
|
|
Commit Message
Uwe Kleine-König
Dec. 24, 2022, 11:56 a.m. UTC
Hello, I work on a patch set that eventually makes the function rtsx_usb_sdmmc_drv_remove() return void: A simplified spatch looks as follows: -------->8-------- virtual patch @p1@ identifier pdev; @@ -int +void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { <... -return 0; +return; ...> } -------->8-------- This results in: -------->8-------- -------->8-------- It's obvious to me, why coccinelle also removes the first return, but it's not obvious to me, how to prevent this and only drop the 2nd one. Do you have a hint for me? Thanks in advance and happy holidays, Uwe
Comments
On Sat, 24 Dec 2022, Uwe Kleine-König wrote: > Hello, > > I work on a patch set that eventually makes the function > rtsx_usb_sdmmc_drv_remove() return void: > > A simplified spatch looks as follows: > > -------->8-------- > virtual patch > > @p1@ > identifier pdev; > @@ > -int > +void > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > <... > -return 0; > +return; > ...> > } > -------->8-------- > > This results in: > > -------->8-------- > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru > return 0; > } > > -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > { > struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); > struct mmc_host *mmc; > > if (!host) > - return 0; > + return; > > mmc = host->mmc; > host->host_removal = true; > @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > dev_dbg(&(pdev->dev), > ": Realtek USB SD/MMC module has been removed\n"); > > - return 0; > + return; > } > > #ifdef CONFIG_PM > -------->8-------- > > which is as intended. Now I want to remove the useless "return;" at the > end of the function, however adding > > -------->8-------- > @p2 depends on p1@ > identifier pdev; > @@ > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > ... > -return; > } > -------->8-------- > > to the spatch doesn't (only) do the intended: The problem is that Coccinelle is following the control-flow through the function, and all of the returns are at the end of a control.flow path. The simple, hacky solution is to change the return;s into some function call Return();, then do like the above for Return(); and then change the Return();s back to return;s julia > > -------->8-------- > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru > return 0; > } > > -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > { > struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); > struct mmc_host *mmc; > > if (!host) > - return 0; > + {} > > mmc = host->mmc; > host->host_removal = true; > @@ -1415,8 +1415,6 @@ static int rtsx_usb_sdmmc_drv_remove(str > > dev_dbg(&(pdev->dev), > ": Realtek USB SD/MMC module has been removed\n"); > - > - return 0; > } > > #ifdef CONFIG_PM > -------->8-------- > > It's obvious to me, why coccinelle also removes the first return, but > it's not obvious to me, how to prevent this and only drop the 2nd one. > > Do you have a hint for me? > > Thanks in advance and happy holidays, > Uwe > > > -- > Pengutronix e.K. | Uwe Kleine-König | > Industrial Linux Solutions | https://www.pengutronix.de/ | >
Hello Julia, first of all thanks for your quick answer. On Sat, Dec 24, 2022 at 01:28:04PM +0100, Julia Lawall wrote: > On Sat, 24 Dec 2022, Uwe Kleine-König wrote: > > A simplified spatch looks as follows: > > > > -------->8-------- > > virtual patch > > > > @p1@ > > identifier pdev; > > @@ > > -int > > +void > > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > <... > > -return 0; > > +return; > > ...> > > } > > -------->8-------- > > > > This results in: > > > > -------->8-------- > > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > > @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru > > return 0; > > } > > > > -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > { > > struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); > > struct mmc_host *mmc; > > > > if (!host) > > - return 0; > > + return; > > > > mmc = host->mmc; > > host->host_removal = true; > > @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > > dev_dbg(&(pdev->dev), > > ": Realtek USB SD/MMC module has been removed\n"); > > > > - return 0; > > + return; > > } > > > > #ifdef CONFIG_PM > > -------->8-------- > > > > which is as intended. Now I want to remove the useless "return;" at the > > end of the function, however adding > > > > -------->8-------- > > @p2 depends on p1@ > > identifier pdev; > > @@ > > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > ... > > -return; > > } > > -------->8-------- > > > > to the spatch doesn't (only) do the intended: > > The problem is that Coccinelle is following the control-flow through the > function, and all of the returns are at the end of a control.flow path. > The simple, hacky solution is to change the return;s into some function > call Return();, then do like the above for Return(); and then change the > Return();s back to return;s OK, I tried, but somehow coccinelle refuse to work after I introduced Return(), even replacing them by return; doesn't work: -------->8-------- virtual patch @p1@ identifier pdev; @@ -int +void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -return 0; +Return(); ... } @p2@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -Return(); +return; ... } -------->8-------- results in -------->8-------- $ /usr/bin/spatch --debug -D patch --very-quiet --cocci-file scripts/coccinelle/api/test.cocci --patch . --dir drivers/mmc/host/rtsx_usb_sdmmc.c -I ./arch/x86/include -I ./arch/x86/include/generated -I ./include -I ./arch/x86/include/uapi -I ./arch/x86/include/generated/uapi -I ./include/uapi -I ./include/generated/uapi --include ./include/linux/compiler-version.h --include ./include/linux/kconfig.h --jobs 4 --chunksize 1 diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1385,7 +1385,7 @@ static int rtsx_usb_sdmmc_drv_remove(str struct mmc_host *mmc; if (!host) - return 0; + Return(); mmc = host->mmc; host->host_removal = true; @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC module has been removed\n"); - return 0; + Return(); } #ifdef CONFIG_PM -------->8-------- Adding --debug doesn't give any hints. (And if I add another hunk inbeetween removing Return at the end of the function there is no effect either.) Do I need to split that in two spatches to make coccinelle cooperate? (If it matters, this is coccinelle as shipped by Debian, Version 1.1.1.deb-2) Best regards Uwe
On Sun, 25 Dec 2022, Uwe Kleine-König wrote: > Hello Julia, > > first of all thanks for your quick answer. > > On Sat, Dec 24, 2022 at 01:28:04PM +0100, Julia Lawall wrote: > > On Sat, 24 Dec 2022, Uwe Kleine-König wrote: > > > A simplified spatch looks as follows: > > > > > > -------->8-------- > > > virtual patch > > > > > > @p1@ > > > identifier pdev; > > > @@ > > > -int > > > +void > > > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > > <... > > > -return 0; > > > +return; > > > ...> > > > } > > > -------->8-------- > > > > > > This results in: > > > > > > -------->8-------- > > > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > > > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > > > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > > > @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru > > > return 0; > > > } > > > > > > -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > > +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > > { > > > struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); > > > struct mmc_host *mmc; > > > > > > if (!host) > > > - return 0; > > > + return; > > > > > > mmc = host->mmc; > > > host->host_removal = true; > > > @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > > > dev_dbg(&(pdev->dev), > > > ": Realtek USB SD/MMC module has been removed\n"); > > > > > > - return 0; > > > + return; > > > } > > > > > > #ifdef CONFIG_PM > > > -------->8-------- > > > > > > which is as intended. Now I want to remove the useless "return;" at the > > > end of the function, however adding > > > > > > -------->8-------- > > > @p2 depends on p1@ > > > identifier pdev; > > > @@ > > > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > > ... > > > -return; > > > } > > > -------->8-------- > > > > > > to the spatch doesn't (only) do the intended: > > > > The problem is that Coccinelle is following the control-flow through the > > function, and all of the returns are at the end of a control.flow path. > > The simple, hacky solution is to change the return;s into some function > > call Return();, then do like the above for Return(); and then change the > > Return();s back to return;s > > OK, I tried, but somehow coccinelle refuse to work after I introduced > Return(), even replacing them by return; doesn't work: > > -------->8-------- > virtual patch > > @p1@ > identifier pdev; > @@ > -int > +void > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > ... > -return 0; > +Return(); > ... > } > > @p2@ > identifier pdev; > @@ > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > ... > -Return(); > +return; > ... > } The problem is that a control-flow path at this point can have multiple calls to Return(); You pattern only matches when every control-flow path through the code has exactly one Return(). You should have one rule that removes the final Return(); @p2@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -Return(); } Then another rule to remove the others: @p2@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { <... -Return(); +return; ...> } julia > -------->8-------- > > results in > > -------->8-------- > $ /usr/bin/spatch --debug -D patch --very-quiet --cocci-file scripts/coccinelle/api/test.cocci --patch . --dir drivers/mmc/host/rtsx_usb_sdmmc.c -I ./arch/x86/include -I ./arch/x86/include/generated -I ./include -I ./arch/x86/include/uapi -I ./arch/x86/include/generated/uapi -I ./include/uapi -I ./include/generated/uapi --include ./include/linux/compiler-version.h --include ./include/linux/kconfig.h --jobs 4 --chunksize 1 > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > @@ -1385,7 +1385,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > struct mmc_host *mmc; > > if (!host) > - return 0; > + Return(); > > mmc = host->mmc; > host->host_removal = true; > @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > dev_dbg(&(pdev->dev), > ": Realtek USB SD/MMC module has been removed\n"); > > - return 0; > + Return(); > } > > #ifdef CONFIG_PM > -------->8-------- > > Adding --debug doesn't give any hints. > > (And if I add another hunk inbeetween removing Return at the end of the > function there is no effect either.) > > Do I need to split that in two spatches to make coccinelle cooperate? > > (If it matters, this is coccinelle as shipped by Debian, Version > 1.1.1.deb-2) > > Best regards > Uwe > > -- > Pengutronix e.K. | Uwe Kleine-König | > Industrial Linux Solutions | https://www.pengutronix.de/ | >
Hello Julia, On Mon, Dec 26, 2022 at 05:02:35PM +0100, Julia Lawall wrote: > On Sun, 25 Dec 2022, Uwe Kleine-König wrote: > > > Hello Julia, > > > > first of all thanks for your quick answer. > > > > On Sat, Dec 24, 2022 at 01:28:04PM +0100, Julia Lawall wrote: > > > On Sat, 24 Dec 2022, Uwe Kleine-König wrote: > > > > A simplified spatch looks as follows: > > > > > > > > -------->8-------- > > > > virtual patch > > > > > > > > @p1@ > > > > identifier pdev; > > > > @@ > > > > -int > > > > +void > > > > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > > > <... > > > > -return 0; > > > > +return; > > > > ...> > > > > } > > > > -------->8-------- > > > > > > > > This results in: > > > > > > > > -------->8-------- > > > > diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c > > > > --- a/drivers/mmc/host/rtsx_usb_sdmmc.c > > > > +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c > > > > @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru > > > > return 0; > > > > } > > > > > > > > -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > > > +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) > > > > { > > > > struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); > > > > struct mmc_host *mmc; > > > > > > > > if (!host) > > > > - return 0; > > > > + return; > > > > > > > > mmc = host->mmc; > > > > host->host_removal = true; > > > > @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str > > > > dev_dbg(&(pdev->dev), > > > > ": Realtek USB SD/MMC module has been removed\n"); > > > > > > > > - return 0; > > > > + return; > > > > } > > > > > > > > #ifdef CONFIG_PM > > > > -------->8-------- > > > > > > > > which is as intended. Now I want to remove the useless "return;" at the > > > > end of the function, however adding > > > > > > > > -------->8-------- > > > > @p2 depends on p1@ > > > > identifier pdev; > > > > @@ > > > > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > > > ... > > > > -return; > > > > } > > > > -------->8-------- > > > > > > > > to the spatch doesn't (only) do the intended: > > > > > > The problem is that Coccinelle is following the control-flow through the > > > function, and all of the returns are at the end of a control.flow path. > > > The simple, hacky solution is to change the return;s into some function > > > call Return();, then do like the above for Return(); and then change the > > > Return();s back to return;s > > > > OK, I tried, but somehow coccinelle refuse to work after I introduced > > Return(), even replacing them by return; doesn't work: > > > > -------->8-------- > > virtual patch > > > > @p1@ > > identifier pdev; > > @@ > > -int > > +void > > rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > ... > > -return 0; > > +Return(); > > ... > > } > > > > @p2@ > > identifier pdev; > > @@ > > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > ... > > -Return(); > > +return; > > ... > > } > > The problem is that a control-flow path at this point can have multiple > calls to Return(); You pattern only matches when every control-flow path > through the code has exactly one Return(). Ah, ok. This wasn't clear to me from reading the documentation (e.g. https://coccinelle.gitlabpages.inria.fr/website/docs/main_grammar.html) > You should have one rule that removes the final Return(); > > @p2@ > identifier pdev; > @@ > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > ... > -Return(); > } > > Then another rule to remove the others: > > @p2@ > identifier pdev; > @@ > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > <... > -Return(); > +return; > ...> > } I now have -------->8-------- virtual patch @p1@ identifier pdev; @@ -int +void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -return 0; +Return(); ... } @p2@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -Return(); } @p3@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { <... -Return(); +return; ...> } -------->8-------- But there p2 suffers from the same problem and only matches code paths with exactly 1 Return(). So the above results in -------->8-------- diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru return 0; } -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); struct mmc_host *mmc; if (!host) - return 0; + return; mmc = host->mmc; host->host_removal = true; @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC module has been removed\n"); - return 0; + return; } #ifdef CONFIG_PM -------->8-------- and only if I remove the "if (!host) return 0;" block before patch generation, the final return is also dropped. I think this is good enough for me, as there are not too many cases like the above. If there is spatch that does the desired change (i.e. -------->8-------- diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1379,13 +1379,11 @@ static int rtsx_usb_sdmmc_drv_probe(stru return 0; } -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); struct mmc_host *mmc; if (!host) - return 0; + return; mmc = host->mmc; host->host_removal = true; @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC module has been removed\n"); - - return 0; } #ifdef CONFIG_PM -------->8-------- ) I'd be happy to hear and learn about it. Thanks Uwe
> @p2@ > identifier pdev; > @@ > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > ... > -Return(); > } You need when any on the ... to allow there to be Returns();s along the way. julia
Hello Julia, On Tue, Dec 27, 2022 at 12:26:50PM +0100, Julia Lawall wrote: > > @p2@ > > identifier pdev; > > @@ > > void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { > > ... > > -Return(); > > } > > You need when any on the ... to allow there to be Returns();s along the > way. \o/ that works fine, thanks (i.e. ... when any instead of ...) Best regards Uwe
diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru return 0; } -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); struct mmc_host *mmc; if (!host) - return 0; + return; mmc = host->mmc; host->host_removal = true; @@ -1416,7 +1416,7 @@ static int rtsx_usb_sdmmc_drv_remove(str dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC module has been removed\n"); - return 0; + return; } #ifdef CONFIG_PM -------->8-------- which is as intended. Now I want to remove the useless "return;" at the end of the function, however adding -------->8-------- @p2 depends on p1@ identifier pdev; @@ void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { ... -return; } -------->8-------- to the spatch doesn't (only) do the intended: -------->8-------- diff -u -p a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1379,13 +1379,13 @@ static int rtsx_usb_sdmmc_drv_probe(stru return 0; } -static int rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) +static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev) { struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev); struct mmc_host *mmc; if (!host) - return 0; + {} mmc = host->mmc; host->host_removal = true; @@ -1415,8 +1415,6 @@ static int rtsx_usb_sdmmc_drv_remove(str dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC module has been removed\n"); - - return 0; } #ifdef CONFIG_PM