On Tue, 18 Oct 2016, Junjie Mao wrote:

> Hi all,
>
> I'm recently collecting collateral evolutions in Linux, inferring the
> patterns in these patches and generate semantic patches for maintainers
> of out-of-tree modules. During the work I am not sure how to express the
> following cases in SmPL.
>
> 1. add a reader for a structure field
>
>     For example, in the following code
>
>      1   int foo(struct device* dev, int mask) {
>      2       int old_flags = dev->flags;
>      3       dev->flags &= mask;
>      4       return (dev->flags == old_flags);
>      5   }
>
>     'dev->flags' need to be replaced by 'dev_flags(dev)' where
>     dev_flags(dev) is a function returning 'dev->flags'. The following
>     semantic patch:
>
>      @@
>      struct device *dev;
>      @@
>      -dev->flags
>      +dev_flags(dev)
>
>     will rewrites all occurences of 'dev->flags', including the one on
>     line 3, which makes the program incorrect. How can I avoid touching
>     line 3 while updating line 2 and line 4 using spatch?

(
dev->flags = e
|
- dev->flags
+ dev_flags(dev)
)

A disjunction should take the first pattern that matches.

>
>     Related commits:
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=2f064f3485cd29633ad1b3cfb00cc519509a3d72
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4d0e965732db6f7cce78e6b8f5d3073249004c3a
>
> 2. rewriting part of a branch condition
>
>      int foo(int i, int j) {
>          if (i > 3 && i < 10 && j > 5 && j < 8)
>              return i;
>          return j;
>      }
>
>     If a commit replaces (i < 10 && j > 5) with (i < 8) (the order of
>     comparisons and logical operators are fixed), how can I express this
>     pattern in SmPL?
>
>     I have tried the following, but it does not work.
>
>      @@
>      identifier foo, i, j;
>      @@
>       foo(int i, int j) {
>           <...
>      -    i < 10 && j > 5
>      +    i < 8
>           ...>
>       }
>
>     Related commit:
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dc3f4198eac14e52a98dfc79cd84b45e280f59cd

This is due to how the && is parsed. a && b && c && d is either parsed as
((a && b) && c) && d or a && (b && (c && d)) (I don't remember which), but
neither has b && c as a sub parse tree.  I think that the only possibility
here is to make some special cases.

> 3. add a statement right after local variable declarations
>
>     In the following function,
>
>      int foo(int i) {
>          int j,k,l;
>
>          j = baz(i);
>          ...
>      }
>
>     How can I add the statement 'bar(i);' before 'j = baz(i)' but after
>     the local variable declarations?

f(...) {
   ... when != S
+  newcode
   S1
   ...
}

Declarations don't match S (statement metavariable).


>     Related commit:
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54efd50bfd873e2dbf784e0b21a8027ba4299a3e
>
> 4. change callback prototypes
>
>     Assume a driver defines a global structure initialized with
>     callbacks:
>
>      1   int foo(int i, int j) { ... }
>      2   int bar(int i, int j) { ... }
>      3
>      4   struct netdev_ops ops = {
>      5       .foo = foo,
>      6   };
>
>     and a commit requires the prototype of the callback being changed to
>     foo(int i, int j, intk), how can I achieve that without touching
>     bar() using spatch?

@r@
identifier i,f;
@@

struct netdev_ops i = { .foo = f, };

@@
identifier r.f;
@@

Now do whatever you want with f

---

julia


>     Related commit:
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=88e72717c2de4181d8a6de1b04315953ad2bebdf
>     - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dece16353ef47d8d33f5302bc158072a9d65e26f
>
> --
> Best Regards
> Junjie Mao
> _______________________________________________
> Cocci mailing list
> Cocci@systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to