From: Julia Lawall <julia.lawall@inria.fr>
To: Akos Pasztory <akos.pasztory@gmail.com>
Cc: cocci@systeme.lip6.fr
Subject: Re: [Cocci] getting rid of implicit boolean expressions
Date: Wed, 21 Apr 2021 21:16:49 +0200 (CEST) [thread overview]
Message-ID: <alpine.DEB.2.22.394.2104212103160.20674@hadrien> (raw)
In-Reply-To: <CAJwHcF6jc_NNGeXpPh0z7upKLXSOuprS=SPmiR-x-QdYxZiEyw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2863 bytes --]
On Wed, 21 Apr 2021, Akos Pasztory wrote:
> Hi,
>
> I'm trying do the following kind of transformations:
>
> int x, y;
> char *p;
> bool b, c;
>
> -b = x || !y;
> +b = (x != 0) || (y == 0);
>
> -c = !p;
> +c = (p == NULL);
>
> -if (x & 3)
> +if ((x & 3) != 0)
> f();
> // etc
>
> That is: trying to eliminate implicit boolean-ness (and add parentheses as well).
>
> I was thinking along the lines of first finding expressions
> that are in "boolean context" (part of a || or && expression,
> or an if/for/while condition, maybe something else too?).
> Then find sub-expressions of those that are not of the form 'E op F'
> where 'op' is a comparison operator (==, !=, <=, ...).
> And finally depending on whether they are pointer or integer and
> whether they are negated, replace them with the above constructs (x != 0, etc.)
>
> Is this the right way to think about this? Meaning does it fit the mental model
> of Coccinelle, or some other approach is needed? (E.g. it crossed my mind to
> maybe match all expressions and try to filter out "unwanted" ones via
> position p != { ... } constraints but that seemed infeasible.)
I think you can do
A simple approach could be:
@@
idexpression *x;
@@
- x
+ (x != NULL)
|| ...
@@
idexpression x;
@@
- x
+ (x != 0)
|| ...
If you want to do function calls, you could do
@@
expression *e;
identifier f;
expression list es;
@@
- f(es)@e
+ (f(es) != NULL)
|| ...
@@
identifier f;
expression list es;
@@
- f(es)
+ (f(es) != 0)
|| ...
Some explanation:
* For pattern || ... there is an isomorphism that allows the pattern to
appear anywhere in the top level of a chain of ||s, including an empty
chain. So it actually should match any expression in a boolean context.
* In the third rule, there is )@e. That means that e should match the
smallest expression that contains the ), which turns out to the be
function call. That way you can talk about the return type of the
function call. A limitation here is that Coccinelle has to be able to
figure out what the type is (this is also a limitation of the first rule
above). If it can't figure out the type of the variable or the return
type of the function call, then the first/third rule will fail and you
will end up with a != 0 test on a pointer. To try to avoid this, you can
use the options --recursive-includes --use-headers-for-types
--relax-include-path to try to take into account as many header files as
possible.
An alternate approach is indeed to do something with position variables.
So you could do something like:
@ok@
position p;
expression e;
expression x;
@@
(x != 0)@e@p
@@
position p != ok.p;
expression x;
@@
- x@p
+ (x != 0)
|| ...
But the first rule would have to be extended to consider lots of cases.
A binary operator metavariable could be helpful, eg:
binary operator bop = { ==, !=, <, > };
julia
[-- Attachment #2: Type: text/plain, Size: 136 bytes --]
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci
prev parent reply other threads:[~2021-04-21 19:16 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-21 18:55 [Cocci] getting rid of implicit boolean expressions Akos Pasztory
2021-04-21 19:16 ` Julia Lawall [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.DEB.2.22.394.2104212103160.20674@hadrien \
--to=julia.lawall@inria.fr \
--cc=akos.pasztory@gmail.com \
--cc=cocci@systeme.lip6.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).