From 177fbab747da4f58cb2a8ce010b3515c86dd67c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Sat, 15 Jun 2019 20:32:58 +0200 Subject: [PATCH 1/2] coccinelle: use COPY_ARRAY for copying arrays The current semantic patch for COPY_ARRAY transforms memcpy(3) calls on pointers, but Coccinelle distinguishes them from arrays. It already contains three rules to handle the options for sizeof (i.e. source, destination and type), and handling arrays as source and destination would require four times as many rules if we enumerated all cases. We also don't handle array subscripts, and supporting that would increase the number of rules by another factor of four. (An isomorphism telling Coccinelle that "sizeof x[...]" is equivalent to "sizeof *x" would be nice..) Support arrays and array subscripts, but keep the number of rules down by adding normalization steps: First turn array subscripts into derefences, then determine the types of expressions used with sizeof and replace them with these types, and then convert the different possible combinations of arrays and pointers with memcpy(3) to COPY_ARRAY. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- contrib/coccinelle/array.cocci | 61 +++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci index 01586821dc..46b8d2ee11 100644 --- a/contrib/coccinelle/array.cocci +++ b/contrib/coccinelle/array.cocci @@ -1,29 +1,60 @@ @@ -type T; -T *dst; -T *src; -expression n; +expression dst, src, n, E; @@ -- memcpy(dst, src, (n) * sizeof(*dst)); -+ COPY_ARRAY(dst, src, n); + memcpy(dst, src, n * sizeof( +- E[...] ++ *(E) + )) @@ type T; -T *dst; -T *src; -expression n; +T *ptr; +T[] arr; +expression E, n; @@ -- memcpy(dst, src, (n) * sizeof(*src)); -+ COPY_ARRAY(dst, src, n); +( + memcpy(ptr, E, +- n * sizeof(*(ptr)) ++ n * sizeof(T) + ) +| + memcpy(arr, E, +- n * sizeof(*(arr)) ++ n * sizeof(T) + ) +| + memcpy(E, ptr, +- n * sizeof(*(ptr)) ++ n * sizeof(T) + ) +| + memcpy(E, arr, +- n * sizeof(*(arr)) ++ n * sizeof(T) + ) +) @@ type T; -T *dst; -T *src; +T *dst_ptr; +T *src_ptr; +T[] dst_arr; +T[] src_arr; expression n; @@ -- memcpy(dst, src, (n) * sizeof(T)); -+ COPY_ARRAY(dst, src, n); +( +- memcpy(dst_ptr, src_ptr, (n) * sizeof(T)) ++ COPY_ARRAY(dst_ptr, src_ptr, n) +| +- memcpy(dst_ptr, src_arr, (n) * sizeof(T)) ++ COPY_ARRAY(dst_ptr, src_arr, n) +| +- memcpy(dst_arr, src_ptr, (n) * sizeof(T)) ++ COPY_ARRAY(dst_arr, src_ptr, n) +| +- memcpy(dst_arr, src_arr, (n) * sizeof(T)) ++ COPY_ARRAY(dst_arr, src_arr, n) +) @@ type T; From 921d49be86bd44ca290c8db6cc6f419dac3ed442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Sat, 15 Jun 2019 20:36:35 +0200 Subject: [PATCH 2/2] use COPY_ARRAY for copying arrays Convert calls of memcpy(3) to use COPY_ARRAY, which shortens and simplifies the code a bit. Patch generated by Coccinelle and contrib/coccinelle/array.cocci. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- fast-import.c | 2 +- kwset.c | 2 +- packfile.c | 6 +++--- pretty.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fast-import.c b/fast-import.c index f38d04fa58..606d44278d 100644 --- a/fast-import.c +++ b/fast-import.c @@ -644,7 +644,7 @@ static struct tree_content *grow_tree_content( struct tree_content *r = new_tree_content(t->entry_count + amt); r->entry_count = t->entry_count; r->delta_depth = t->delta_depth; - memcpy(r->entries,t->entries,t->entry_count*sizeof(t->entries[0])); + COPY_ARRAY(r->entries, t->entries, t->entry_count); release_tree_content(t); return r; } diff --git a/kwset.c b/kwset.c index 4fb6455aca..090ffcafa2 100644 --- a/kwset.c +++ b/kwset.c @@ -475,7 +475,7 @@ kwsprep (kwset_t kws) for (i = 0; i < NCHAR; ++i) kwset->next[i] = next[U(trans[i])]; else - memcpy(kwset->next, next, NCHAR * sizeof(struct trie *)); + COPY_ARRAY(kwset->next, next, NCHAR); } /* Fix things up for any translation table. */ diff --git a/packfile.c b/packfile.c index 49c8544ff4..2ff570fbfd 100644 --- a/packfile.c +++ b/packfile.c @@ -1269,7 +1269,7 @@ static enum object_type packed_to_object_type(struct repository *r, if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) { poi_stack_alloc = alloc_nr(poi_stack_nr); ALLOC_ARRAY(poi_stack, poi_stack_alloc); - memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr); + COPY_ARRAY(poi_stack, small_poi_stack, poi_stack_nr); } else { ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc); } @@ -1679,8 +1679,8 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, && delta_stack == small_delta_stack) { delta_stack_alloc = alloc_nr(delta_stack_nr); ALLOC_ARRAY(delta_stack, delta_stack_alloc); - memcpy(delta_stack, small_delta_stack, - sizeof(*delta_stack)*delta_stack_nr); + COPY_ARRAY(delta_stack, small_delta_stack, + delta_stack_nr); } else { ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc); } diff --git a/pretty.c b/pretty.c index ced0485257..e4ed14effe 100644 --- a/pretty.c +++ b/pretty.c @@ -106,8 +106,8 @@ static void setup_commit_formats(void) commit_formats_len = ARRAY_SIZE(builtin_formats); builtin_formats_len = commit_formats_len; ALLOC_GROW(commit_formats, commit_formats_len, commit_formats_alloc); - memcpy(commit_formats, builtin_formats, - sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats)); + COPY_ARRAY(commit_formats, builtin_formats, + ARRAY_SIZE(builtin_formats)); git_config(git_pretty_formats_config, NULL); }