git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] builtin/mv.c: use correct type to compute size of an array element

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Jul 7, 2022, 12:11 UTC
Message-ID
<220707.86y1x585wy.gmgdl@evledraar.gmail.com>
In-Reply-To
<xmqq8rp54r4l.fsf@gitster.g>
On Wed, Jul 06 2022, Junio C Hamano wrote:
Show 55 quoted lines
> The variables 'source', 'destination', and 'submodule_gitfile' are
> all of type "const char **", and an element of such an array is of
> "type const char *".
>
> Noticed while running "make contrib/coccinelle/array.cocci.patch".
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>
>  * There is this rule in the array.cocci file:
>
>         @@
>         type T;
>         T *dst;
>         T *src;
>         expression n;
>         @@
>         (
>         - memmove(dst, src, (n) * sizeof(*dst));
>         + MOVE_ARRAY(dst, src, n);
>         |
>         - memmove(dst, src, (n) * sizeof(*src));
>         + MOVE_ARRAY(dst, src, n);
>         |
>         - memmove(dst, src, (n) * sizeof(T));
>         + MOVE_ARRAY(dst, src, n);
>         )
>
>    but it triggered only for modes[] array among the four parallel
>    arrays that are being moved here.
>
>    There are a few tangents.
>
>    * Should we in general use sizeof(TYPE) in these cases, instead
>      of the size of the zeroth element, e.g.
>
>  		memmove(source + i, source + i + 1,
> 			n * sizeof(source[i]));
>     
>      It would have been caught by the above Coccinelle rule (we are
>      taking the size of *dst).
>
>    * Shouldn't we have an array of struct with four members, instead
>      of four parallel arrays, e.g.
>
> 		struct {
> 			const char *source;
> 			const char *destination;
> 			enum update_mode mode;
> 			const char *submodule_gitfile;
> 		} *mv_file;
>
>    The latter question is important to answer before we accept
>    Coccinelle-suggested rewrite to use four MOVE_ARRAY() on these
>    four parallel arrays on top of this fix.

This seems to be the same sort case as noted in 7bd97d6dff3 (git: use COPY_ARRAY and MOVE_ARRAY in handle_alias(), 2019-09-19).

I tried (going aginst the warnings in that commit about the non-generality) updating the rules to catch these cases, which yielded the below. I wonder if we should apply some version of it. I.e. one-off fix these, and perhaps have the cocci rule BUG() if we see this sort of code again (the form technically could be used, but it seems all our uses of it are ones we could convert to the simpler one...).

diff --git a/add-patch.c b/add-patch.c
index 509ca04456b..eff338d3901 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -915,10 +915,9 @@ static int split_hunk(struct add_p_state *s, struct file_diff *file_diff,
 	file_diff->hunk_nr += splittable_into - 1;
 	ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr, file_diff->hunk_alloc);
 	if (hunk_index + splittable_into < file_diff->hunk_nr)
-		memmove(file_diff->hunk + hunk_index + splittable_into,
-			file_diff->hunk + hunk_index + 1,
-			(file_diff->hunk_nr - hunk_index - splittable_into)
-			* sizeof(*hunk));
+		MOVE_ARRAY(file_diff->hunk + hunk_index + splittable_into,
+			   file_diff->hunk + hunk_index + 1,
+			   file_diff->hunk_nr - hunk_index - splittable_into);
 	hunk = file_diff->hunk + hunk_index;
 	hunk->splittable_into = 1;
 	memset(hunk + 1, 0, (splittable_into - 1) * sizeof(*hunk));
diff --git a/builtin/mv.c b/builtin/mv.c
index 83a465ba831..f6187d1264a 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -282,14 +282,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 remove_entry:
 		if (--argc > 0) {
 			int n = argc - i;
-			memmove(source + i, source + i + 1,
-				n * sizeof(char *));
-			memmove(destination + i, destination + i + 1,
-				n * sizeof(char *));
-			memmove(modes + i, modes + i + 1,
-				n * sizeof(enum update_mode));
-			memmove(submodule_gitfile + i, submodule_gitfile + i + 1,
-				n * sizeof(char *));
+			MOVE_ARRAY(source + i, source + i + 1, n);
+			MOVE_ARRAY(destination + i, destination + i + 1, n);
+			MOVE_ARRAY(modes + i, modes + i + 1, n);
+			MOVE_ARRAY(submodule_gitfile + i,
+				   submodule_gitfile + i + 1, n);
 			i--;
 		}
 	}
diff --git a/commit.c b/commit.c
index 1fb1b2ea90c..c23d3e3678f 100644
--- a/commit.c
+++ b/commit.c
@@ -151,10 +151,9 @@ int register_commit_graft(struct repository *r, struct commit_graft *graft,
 		   r->parsed_objects->grafts_alloc);
 	r->parsed_objects->grafts_nr++;
 	if (pos < r->parsed_objects->grafts_nr)
-		memmove(r->parsed_objects->grafts + pos + 1,
-			r->parsed_objects->grafts + pos,
-			(r->parsed_objects->grafts_nr - pos - 1) *
-			sizeof(*r->parsed_objects->grafts));
+		MOVE_ARRAY(r->parsed_objects->grafts + pos + 1,
+			   r->parsed_objects->grafts + pos,
+			   r->parsed_objects->grafts_nr - pos - 1);
 	r->parsed_objects->grafts[pos] = graft;
 	unparse_commit(r, &graft->oid);
 	return 0;
diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci
index 9a4f00cb1bd..988ff9a3fda 100644
--- a/contrib/coccinelle/array.cocci
+++ b/contrib/coccinelle/array.cocci
@@ -73,6 +73,15 @@ expression n;
 + MOVE_ARRAY(dst, src, n);
 )
 
+@@
+expression D;
+expression S;
+expression N;
+expression Z;
+@@
+- memmove(D, S, (N) * Z);
++ MOVE_ARRAY(D, S, N);
+
 @@
 type T;
 T *ptr;
Previous: Derrick StoleeNext: Junio C Hamano
Message 5 of 18 in “builtin/mv.c: use correct type to compute size of an array element”
  1. builtin/mv.c: use correct type to compute size of an array elementJunio C Hamano, Jul 7, 2022
  2. builtin/mv.c: use the MOVE_ARRAY() macro instead of memmove()Junio C Hamano, Jul 7, 2022
  3. builtin/mv.c: use the MOVE_ARRAY() macro instead of memmove()Junio C Hamano, Jul 10, 2022
  4. Derrick StoleeJul 18, 2022
  5. Ævar Arnfjörð BjarmasonJul 7, 2022
  6. Junio C HamanoJul 7, 2022
  7. René ScharfeJul 7, 2022
  8. René ScharfeJul 9, 2022
  9. Junio C HamanoJul 10, 2022
  10. cocci: avoid normalization rules for memcpyRené Scharfe, Jul 10, 2022
  11. Ævar Arnfjörð BjarmasonJul 10, 2022
  12. Ævar Arnfjörð BjarmasonJul 10, 2022
  13. Junio C HamanoJul 10, 2022
  14. René ScharfeJul 11, 2022
  15. Ævar Arnfjörð BjarmasonJul 11, 2022
  16. René ScharfeJul 7, 2022
  17. Jeff KingJul 7, 2022
  18. Junio C HamanoJul 7, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.