use COPY_ARRAY

Add a semantic patch for converting certain calls of memcpy(3) to COPY_ARRAY() and apply that transformation to the code base. The result is shorter and safer code. For now only consider calls where source and destination have the same type, or in other words: easy cases. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Sep 25, 2016 at 09:24 UTC 45ccef87b3cc0ab09ec5fd1186aa0b33298ee8d4
6 files changed +32 -9
builtin/mv.c
+1 -1
@@ -26,7 +26,7 @@ static const char **internal_copy_pathspec(const char *prefix,
26 int i;
27 const char **result;
28 ALLOC_ARRAY(result, count + 1);
29 - memcpy(result, pathspec, count * sizeof(const char *));
29 + COPY_ARRAY(result, pathspec, count);
30 result[count] = NULL;
31 for (i = 0; i < count; i++) {
32 int length = strlen(result[i]);
commit.c
+1 -1
@@ -931,7 +931,7 @@ static int remove_redundant(struct commit **array, int cnt)
931 }
932
933 /* Now collect the result */
934 - memcpy(work, array, sizeof(*array) * cnt);
934 + COPY_ARRAY(work, array, cnt);
935 for (i = filled = 0; i < cnt; i++)
936 if (!redundant[i])
937 array[filled++] = work[i];
contrib/coccinelle/array.cocci new
+26
@@ -0,0 +1,26 @@
1 +@@
2 +type T;
3 +T *dst;
4 +T *src;
5 +expression n;
6 +@@
7 +- memcpy(dst, src, n * sizeof(*dst));
8 ++ COPY_ARRAY(dst, src, n);
9 +
10 +@@
11 +type T;
12 +T *dst;
13 +T *src;
14 +expression n;
15 +@@
16 +- memcpy(dst, src, n * sizeof(*src));
17 ++ COPY_ARRAY(dst, src, n);
18 +
19 +@@
20 +type T;
21 +T *dst;
22 +T *src;
23 +expression n;
24 +@@
25 +- memcpy(dst, src, n * sizeof(T));
26 ++ COPY_ARRAY(dst, src, n);
pack-revindex.c
+1 -1
@@ -107,7 +107,7 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max)
107 * we have to move it back from the temporary storage.
108 */
109 if (from != entries)
110 - memcpy(entries, tmp, n * sizeof(*entries));
110 + COPY_ARRAY(entries, tmp, n);
111 free(tmp);
112 free(pos);
113
pathspec.c
+1 -2
@@ -485,8 +485,7 @@ void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
485 {
486 *dst = *src;
487 ALLOC_ARRAY(dst->items, dst->nr);
488 - memcpy(dst->items, src->items,
489 - sizeof(struct pathspec_item) * dst->nr);
488 + COPY_ARRAY(dst->items, src->items, dst->nr);
489 }
490
491 void clear_pathspec(struct pathspec *pathspec)
split-index.c
+2 -4
@@ -83,8 +83,7 @@ void move_cache_to_base_index(struct index_state *istate)
83 si->base->timestamp = istate->timestamp;
84 ALLOC_GROW(si->base->cache, istate->cache_nr, si->base->cache_alloc);
85 si->base->cache_nr = istate->cache_nr;
86 - memcpy(si->base->cache, istate->cache,
87 - sizeof(*istate->cache) * istate->cache_nr);
86 + COPY_ARRAY(si->base->cache, istate->cache, istate->cache_nr);
87 mark_base_index_entries(si->base);
88 for (i = 0; i < si->base->cache_nr; i++)
89 si->base->cache[i]->ce_flags &= ~CE_UPDATE_IN_BASE;
@@ -141,8 +140,7 @@ void merge_base_index(struct index_state *istate)
140 istate->cache = NULL;
141 istate->cache_alloc = 0;
142 ALLOC_GROW(istate->cache, istate->cache_nr, istate->cache_alloc);
144 - memcpy(istate->cache, si->base->cache,
145 - sizeof(*istate->cache) * istate->cache_nr);
143 + COPY_ARRAY(istate->cache, si->base->cache, istate->cache_nr);
144
145 si->nr_deletions = 0;
146 si->nr_replacements = 0;