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? 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 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? 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? 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