{"thread":{"id":"64908","subject":"[PATCH] cocci: extend MEMZERO_ARRAY() rules","startedAt":"2026-02-03T10:29:27Z","lastAt":"2026-02-03T19:16:31Z","messageCount":2,"participants":["Toon Claes","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"535055","messageId":"20260203102908.749954-1-toon@iotcl.com","threadId":"64908","inReplyTo":null,"subject":"[PATCH] cocci: extend MEMZERO_ARRAY() rules","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2026-02-03T10:29:03Z","receivedAt":"2026-02-03T10:29:27Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"In December we've added the MEMZERO_ARRAY() macro. I wrote the initial version,\nand Junio made improvements to it. But I realized not all cases where\nMEMZERO_ARRAY() was used were detected by coccinelle. So I've been improving the\nrules further. But due to the holidays I forgot had this patch laying around,\nand now during cleanup I ran into it again.\n\nAs far as I can tell, all cases that now use MEMZERO_ARRAY() would have been\nconverted by coccinelle automatically.\n\nAs pointed out by René[1], \"0x0\" can be replaced by \"0\", and coccinelle can also\nbe used to drop unneeded parentheses.\n\nI'm not entirely sure it's worth applying this patch, as the original\nMEMZERO_ARRAY() date back a month or two. So I don't mind if this patch would be\ndismissed.\n\n[1]: https://lore.kernel.org/git/f02b628f-b9d7-4436-88ee-3255e02cb0f3@web.de/\n\n\nKind regards,\nToon\n\n-- 8< --\n\nRecently the MEMZERO_ARRAY() macro was introduced. In that commit also\ncoccinelle rules were added to capture cases that can be converted to\nuse that macro.\n\nLater a few more cases were manually converted to use the macro, but\ncoccinelle didn't capture those. Extend the rules to capture those as\nwell.\n\nIn various cases the code could be further beautified by removing\nparentheses which are no longer needed. Modify the coccinelle rules to\noptimize those as well and fix them.\n\nDuring conversion indentation also used spaces where tabs should be\nused, fix that in one go.\n\nSigned-off-by: Toon Claes <toon@iotcl.com>\n---\n contrib/coccinelle/array.cocci | 36 ++++++++++++++++++++++++++++------\n diffcore-delta.c               |  2 +-\n ewah/bitmap.c                  |  4 ++--\n 3 files changed, 33 insertions(+), 9 deletions(-)\n\ndiff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci\nindex d306f6a21e..e71baea00b 100644\n--- a/contrib/coccinelle/array.cocci\n+++ b/contrib/coccinelle/array.cocci\n@@ -107,9 +107,32 @@ type T;\n T *ptr;\n expression n;\n @@\n-- memset(ptr, \\( 0x0 \\| 0 \\), n * \\( sizeof(T)\n--                                 \\| sizeof(*ptr)\n--                                 \\) )\n+- memset(ptr, \\( 0 \\| '\\0' \\), \\( (n) \\| n \\) * \\( sizeof(T)\n+-                                               \\| sizeof(ptr[...])\n+-                                               \\| sizeof(*ptr)\n+-                                               \\) )\n++ MEMZERO_ARRAY(ptr, n)\n+\n+@@\n+type T;\n+T *ptr;\n+expression n;\n+@@\n+- memset(ptr, \\( 0 \\| '\\0' \\), \\( sizeof(T)\n+-                              \\| sizeof(ptr[...])\n+-                              \\| sizeof(*ptr)\n+-                              \\) * \\( (n) \\| n \\) )\n++ MEMZERO_ARRAY(ptr, n)\n+\n+@@\n+type T;\n+T[] ptr;\n+expression n;\n+@@\n+- memset(ptr, \\( 0 \\| '\\0' \\), \\( (n) \\| n \\) * \\( sizeof(T)\n+-                                               \\| sizeof(ptr[...])\n+-                                               \\| sizeof(*ptr)\n+-                                               \\) )\n + MEMZERO_ARRAY(ptr, n)\n\n @@\n@@ -117,7 +140,8 @@ type T;\n T[] ptr;\n expression n;\n @@\n-- memset(ptr, \\( 0x0 \\| 0 \\), n * \\( sizeof(T)\n--                                 \\| sizeof(*ptr)\n--                                 \\) )\n+- memset(ptr, \\( 0 \\| '\\0' \\), \\( sizeof(T)\n+-                              \\| sizeof(ptr[...])\n+-                              \\| sizeof(*ptr)\n+-                              \\) * \\( (n) \\| n \\) )\n + MEMZERO_ARRAY(ptr, n)\ndiff --git a/diffcore-delta.c b/diffcore-delta.c\nindex 2de9e9ccff..2b7db39983 100644\n--- a/diffcore-delta.c\n+++ b/diffcore-delta.c\n@@ -135,7 +135,7 @@ static struct spanhash_top *hash_chars(struct repository *r,\n \t\t\t      st_mult(sizeof(struct spanhash), (size_t)1 << i)));\n \thash->alloc_log2 = i;\n \thash->free = INITIAL_FREE(i);\n-\tMEMZERO_ARRAY(hash->data, ((size_t)1 << i));\n+\tMEMZERO_ARRAY(hash->data, (size_t)1 << i);\n\n \tn = 0;\n \taccum1 = accum2 = 0;\ndiff --git a/ewah/bitmap.c b/ewah/bitmap.c\nindex bf878bf876..c378e0ab78 100644\n--- a/ewah/bitmap.c\n+++ b/ewah/bitmap.c\n@@ -46,7 +46,7 @@ static void bitmap_grow(struct bitmap *self, size_t word_alloc)\n {\n \tsize_t old_size = self->word_alloc;\n \tALLOC_GROW(self->words, word_alloc, self->word_alloc);\n-\tMEMZERO_ARRAY(self->words + old_size, (self->word_alloc - old_size));\n+\tMEMZERO_ARRAY(self->words + old_size, self->word_alloc - old_size);\n }\n\n void bitmap_set(struct bitmap *self, size_t pos)\n@@ -192,7 +192,7 @@ void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other)\n \t\tself->word_alloc = other_final;\n \t\tREALLOC_ARRAY(self->words, self->word_alloc);\n \t\tMEMZERO_ARRAY(self->words + original_size,\n-\t\t              (self->word_alloc - original_size));\n+\t\t\t      self->word_alloc - original_size);\n \t}\n\n \tewah_iterator_init(&it, other);\n--\n2.53.0.rc1.267.g6e3a78c723\n"},{"id":"535085","messageId":"xmqqjywtskmr.fsf@gitster.g","threadId":"64908","inReplyTo":"20260203102908.749954-1-toon@iotcl.com","subject":"Re: [PATCH] cocci: extend MEMZERO_ARRAY() rules","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-03T19:16:28Z","receivedAt":"2026-02-03T19:16:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Toon Claes <toon@iotcl.com> writes:\n\n> Recently the MEMZERO_ARRAY() macro was introduced. In that commit also\n> coccinelle rules were added to capture cases that can be converted to\n> use that macro.\n>\n> Later a few more cases were manually converted to use the macro, but\n> coccinelle didn't capture those. Extend the rules to capture those as\n> well.\n>\n> In various cases the code could be further beautified by removing\n> parentheses which are no longer needed. Modify the coccinelle rules to\n> optimize those as well and fix them.\n>\n> During conversion indentation also used spaces where tabs should be\n> used, fix that in one go.\n>\n> Signed-off-by: Toon Claes <toon@iotcl.com>\n> ---\n>  contrib/coccinelle/array.cocci | 36 ++++++++++++++++++++++++++++------\n>  diffcore-delta.c               |  2 +-\n>  ewah/bitmap.c                  |  4 ++--\n>  3 files changed, 33 insertions(+), 9 deletions(-)\n>\n> diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci\n> index d306f6a21e..e71baea00b 100644\n> --- a/contrib/coccinelle/array.cocci\n> +++ b/contrib/coccinelle/array.cocci\n> @@ -107,9 +107,32 @@ type T;\n>  T *ptr;\n>  expression n;\n>  @@\n> -- memset(ptr, \\( 0x0 \\| 0 \\), n * \\( sizeof(T)\n> --                                 \\| sizeof(*ptr)\n> --                                 \\) )\n> +- memset(ptr, \\( 0 \\| '\\0' \\), \\( (n) \\| n \\) * \\( sizeof(T)\n> +-                                               \\| sizeof(ptr[...])\n> +-                                               \\| sizeof(*ptr)\n> +-                                               \\) )\n\nIt is kind-a surprising that (n) with and without parentheses must\nbe presented for the conversion to happen, while the tool clearly\nunderstands that 0 and 0x0 are equivalent ...\n\n> ++ MEMZERO_ARRAY(ptr, n)\n> +\n> +@@\n> +type T;\n> +T *ptr;\n> +expression n;\n> +@@\n> +- memset(ptr, \\( 0 \\| '\\0' \\), \\( sizeof(T)\n> +-                              \\| sizeof(ptr[...])\n> +-                              \\| sizeof(*ptr)\n> +-                              \\) * \\( (n) \\| n \\) )\n\n... and yet the tool does not understand the equivalence between\n'\\0' and 0, nor (A * B) and (B * A).  Puzzling, but OK.\n\nAnd the pattern, with *ptr  substituted to ptr[], repeats.\n\n> diff --git a/diffcore-delta.c b/diffcore-delta.c\n> index 2de9e9ccff..2b7db39983 100644\n> --- a/diffcore-delta.c\n> +++ b/diffcore-delta.c\n> @@ -135,7 +135,7 @@ static struct spanhash_top *hash_chars(struct repository *r,\n>  \t\t\t      st_mult(sizeof(struct spanhash), (size_t)1 << i)));\n>  \thash->alloc_log2 = i;\n>  \thash->free = INITIAL_FREE(i);\n> -\tMEMZERO_ARRAY(hash->data, ((size_t)1 << i));\n> +\tMEMZERO_ARRAY(hash->data, (size_t)1 << i);\n>\n>  \tn = 0;\n>  \taccum1 = accum2 = 0;\n> diff --git a/ewah/bitmap.c b/ewah/bitmap.c\n> index bf878bf876..c378e0ab78 100644\n> --- a/ewah/bitmap.c\n> +++ b/ewah/bitmap.c\n> @@ -46,7 +46,7 @@ static void bitmap_grow(struct bitmap *self, size_t word_alloc)\n>  {\n>  \tsize_t old_size = self->word_alloc;\n>  \tALLOC_GROW(self->words, word_alloc, self->word_alloc);\n> -\tMEMZERO_ARRAY(self->words + old_size, (self->word_alloc - old_size));\n> +\tMEMZERO_ARRAY(self->words + old_size, self->word_alloc - old_size);\n>  }\n>\n>  void bitmap_set(struct bitmap *self, size_t pos)\n> @@ -192,7 +192,7 @@ void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other)\n>  \t\tself->word_alloc = other_final;\n>  \t\tREALLOC_ARRAY(self->words, self->word_alloc);\n>  \t\tMEMZERO_ARRAY(self->words + original_size,\n> -\t\t              (self->word_alloc - original_size));\n> +\t\t\t      self->word_alloc - original_size);\n>  \t}\n>\n>  \tewah_iterator_init(&it, other);\n\nOK.  These do look easier to follow without extra parentheses.\n\nWill queue.  Thanks.\n"}]}