brian m. carlson | db1d80b | 2016-06-24 23:09:20 +0000 | [diff] [blame] | 1 | This directory provides examples of Coccinelle (http://coccinelle.lip6.fr/) |
| 2 | semantic patches that might be useful to developers. |
SZEDER Gábor | dd5d052 | 2018-11-09 16:10:52 -0800 | [diff] [blame] | 3 | |
| 4 | There are two types of semantic patches: |
| 5 | |
| 6 | * Using the semantic transformation to check for bad patterns in the code; |
| 7 | The target 'make coccicheck' is designed to check for these patterns and |
| 8 | it is expected that any resulting patch indicates a regression. |
| 9 | The patches resulting from 'make coccicheck' are small and infrequent, |
| 10 | so once they are found, they can be sent to the mailing list as per usual. |
| 11 | |
| 12 | Example for introducing new patterns: |
| 13 | 67947c34ae (convert "hashcmp() != 0" to "!hasheq()", 2018-08-28) |
| 14 | b84c783882 (fsck: s/++i > 1/i++/, 2018-10-24) |
| 15 | |
| 16 | Example of fixes using this approach: |
| 17 | 248f66ed8e (run-command: use strbuf_addstr() for adding a string to |
| 18 | a strbuf, 2018-03-25) |
| 19 | f919ffebed (Use MOVE_ARRAY, 2018-01-22) |
| 20 | |
| 21 | These types of semantic patches are usually part of testing, c.f. |
| 22 | 0860a7641b (travis-ci: fail if Coccinelle static analysis found something |
| 23 | to transform, 2018-07-23) |
| 24 | |
| 25 | * Using semantic transformations in large scale refactorings throughout |
| 26 | the code base. |
| 27 | |
| 28 | When applying the semantic patch into a real patch, sending it to the |
| 29 | mailing list in the usual way, such a patch would be expected to have a |
| 30 | lot of textual and semantic conflicts as such large scale refactorings |
| 31 | change function signatures that are used widely in the code base. |
| 32 | A textual conflict would arise if surrounding code near any call of such |
| 33 | function changes. A semantic conflict arises when other patch series in |
| 34 | flight introduce calls to such functions. |
| 35 | |
| 36 | So to aid these large scale refactorings, semantic patches can be used. |
| 37 | However we do not want to store them in the same place as the checks for |
| 38 | bad patterns, as then automated builds would fail. |
| 39 | That is why semantic patches 'contrib/coccinelle/*.pending.cocci' |
| 40 | are ignored for checks, and can be applied using 'make coccicheck-pending'. |
| 41 | |
| 42 | This allows to expose plans of pending large scale refactorings without |
| 43 | impacting the bad pattern checks. |
Ævar Arnfjörð Bjarmason | 316e388 | 2022-11-01 23:35:51 +0100 | [diff] [blame] | 44 | |
| 45 | Git-specific tips & things to know about how we run "spatch": |
| 46 | |
| 47 | * The "make coccicheck" will piggy-back on |
| 48 | "COMPUTE_HEADER_DEPENDENCIES". If you've built a given object file |
| 49 | the "coccicheck" target will consider its depednency to decide if |
| 50 | it needs to re-run on the corresponding source file. |
| 51 | |
| 52 | This means that a "make coccicheck" will re-compile object files |
| 53 | before running. This might be unexpected, but speeds up the run in |
| 54 | the common case, as e.g. a change to "column.h" won't require all |
| 55 | coccinelle rules to be re-run against "grep.c" (or another file |
| 56 | that happens not to use "column.h"). |
| 57 | |
| 58 | To disable this behavior use the "SPATCH_USE_O_DEPENDENCIES=NoThanks" |
| 59 | flag. |
Ævar Arnfjörð Bjarmason | d0e624a | 2022-11-01 23:35:54 +0100 | [diff] [blame] | 60 | |
| 61 | * To speed up our rules the "make coccicheck" target will by default |
| 62 | concatenate all of the *.cocci files here into an "ALL.cocci", and |
| 63 | apply it to each source file. |
| 64 | |
| 65 | This makes the run faster, as we don't need to run each rule |
| 66 | against each source file. See the Makefile for further discussion, |
| 67 | this behavior can be disabled with "SPATCH_CONCAT_COCCI=". |
| 68 | |
| 69 | But since they're concatenated any <id> in the <rulname> (e.g. "@ |
| 70 | my_name", v.s. anonymous "@@") needs to be unique across all our |
| 71 | *.cocci files. You should only need to name rules if other rules |
| 72 | depend on them (currently only one rule is named). |
Ævar Arnfjörð Bjarmason | 6fae3aa | 2022-11-01 23:35:55 +0100 | [diff] [blame] | 73 | |
| 74 | * To speed up incremental runs even more use the "spatchcache" tool |
| 75 | in this directory as your "SPATCH". It aimns to be a "ccache" for |
| 76 | coccinelle, and piggy-backs on "COMPUTE_HEADER_DEPENDENCIES". |
| 77 | |
| 78 | It caches in Redis by default, see it source for a how-to. |
| 79 | |
| 80 | In one setup with a primed cache "make coccicheck" followed by a |
| 81 | "make clean && make" takes around 10s to run, but 2m30s with the |
| 82 | default of "SPATCH_CONCAT_COCCI=Y". |
| 83 | |
| 84 | With "SPATCH_CONCAT_COCCI=" the total runtime is around ~6m, sped |
| 85 | up to ~1m with "spatchcache". |
| 86 | |
| 87 | Most of the 10s (or ~1m) being spent on re-running "spatch" on |
| 88 | files we couldn't cache, as we didn't compile them (in contrib/* |
| 89 | and compat/* mostly). |
| 90 | |
| 91 | The absolute times will differ for you, but the relative speedup |
| 92 | from caching should be on that order. |