On Wed, 9 Mar 2011, Dan McGee wrote:

> On Wed, Mar 9, 2011 at 10:09 AM, Julia Lawall <[email protected]> wrote:
> > The solution is not to actually perform any transformations on the
> > subexpressions a and b.  The example works fine with the following
> > semantic patch:
> >
> > @ oper_add @
> > expression a, b;
> > @@
> > - oper_add(
> >  a
> > - ,
> > + +
> >  b
> > - )
> >
> > The only small unfortunate bit is that the pretty printing is not very
> > nice.  It doesn't realize that + is a binary operator, and so there is no
> > space before it, although there is a space after it.  It should be
> > possible to fix this.
> 
> Thanks for the hint here- I ended up finding something that did work
> closer to expected and formats it relatively nicely as it seems to
> recognize the binary operator:
> @@
> expression a, b;
> @@
> - oper_add(a,
> + a +
>   b
> - )
> 
> One more question. I'm looking now at a follow-on transform to the
> above to simplify things more, and this works for the simple case, but
> not the follow-on cases.
> a = a + 1; --> a+= 1;
> b = b + a + 1 --> does not get transformed.
> 
> expression a, b;
> @@
> - a = ((a) + (b));
> + a += b;

This is a bit more complicated.  The problem is the associativity of +.  + 
associates to the left, and you want it to associate to the right.  If you 
write a + ..., ie with ... as the other argument, then it will consider 
any sum with a at the top level.  This works for various associative 
operators (eg || and &&).  Butthe problem is that you can't use ... 
because you need b to construct the new code.  And if you organize things 
such that b doesn't have to be in the + code, ie it could be expressed as 
..., then coccinelle is not able to verify that this isomorphism for + 
and ... is safe to apply.

A solution is to identify the case first and then make the transformation 
in a separate rule:

@r@
expression a;
position p;
@@

a =@p a + ...;

@@
expression a, b;
position r.p;
@@

a
- =@p
+ +=
 <+... 
- a + b
+ b
 ...+>;

This works for the first two ofteh following functions, but not for the 
third one, because then there are two matches that express different 
transformations:

int main () {
  b = b + a + 1;
}

int main () {
  b = 1 + a + b;
}

int main () {
  b = b + a + b;
}

julia
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to