add MOVE_ARRAY

Similar to COPY_ARRAY (introduced in 60566cbb58), add a safe and convenient helper for moving potentially overlapping ranges of array entries. It infers the element size, multiplies automatically and safely to get the size in bytes, does a basic type safety check by comparing element sizes and unlike memmove(3) it supports NULL pointers iff 0 elements are to be moved. Also add a semantic patch to demonstrate the helper's intended usage. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jul 15, 2017 at 21:36 UTC 578398071e45d296c3dc1de10acdbc15365e763f
2 files changed +25
contrib/coccinelle/array.cocci
+17
@@ -25,6 +25,23 @@ expression n;
25 - memcpy(dst, src, n * sizeof(T));
26 + COPY_ARRAY(dst, src, n);
27
28 +@@
29 +type T;
30 +T *dst;
31 +T *src;
32 +expression n;
33 +@@
34 +(
35 +- memmove(dst, src, (n) * sizeof(*dst));
36 ++ MOVE_ARRAY(dst, src, n);
37 +|
38 +- memmove(dst, src, (n) * sizeof(*src));
39 ++ MOVE_ARRAY(dst, src, n);
40 +|
41 +- memmove(dst, src, (n) * sizeof(T));
42 ++ MOVE_ARRAY(dst, src, n);
43 +)
44 +
45 @@
46 type T;
47 T *ptr;
git-compat-util.h
+8
@@ -825,6 +825,14 @@ static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
825 memcpy(dst, src, st_mult(size, n));
826 }
827
828 +#define MOVE_ARRAY(dst, src, n) move_array((dst), (src), (n), sizeof(*(dst)) + \
829 + BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
830 +static inline void move_array(void *dst, const void *src, size_t n, size_t size)
831 +{
832 + if (n)
833 + memmove(dst, src, st_mult(size, n));
834 +}
835 +
836 /*
837 * These functions help you allocate structs with flex arrays, and copy
838 * the data directly into the array. For example, if you had: