Re: [PATCH 1/2] add MOVE_ARRAY
On Sat, Jul 15, 2017 at 09:36:20PM +0200, René Scharfe wrote: > 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. If we have COPY_ARRAY(), I think it's foolish not to provide the matching MOVE_ARRAY(). If it were just the "if (n)", I might say we could just do this inline in the few calls that care. But I really like the size safety. I agree with your comments elsewhere that we don't need to worry about the case where one of the arrays is NULL but the size is not zero. That's a flat-out bug. -Peff
[PATCH 1/2] 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--- contrib/coccinelle/array.cocci | 17 + git-compat-util.h | 8 2 files changed, 25 insertions(+) diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci index 4ba98b7eaf..c61d1ca8dc 100644 --- a/contrib/coccinelle/array.cocci +++ b/contrib/coccinelle/array.cocci @@ -27,6 +27,23 @@ expression n; @@ 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); +) + +@@ +type T; T *ptr; expression n; @@ diff --git a/git-compat-util.h b/git-compat-util.h index 047172d173..159f82154a 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -825,6 +825,14 @@ static inline void copy_array(void *dst, const void *src, size_t n, size_t size) memcpy(dst, src, st_mult(size, n)); } +#define MOVE_ARRAY(dst, src, n) move_array((dst), (src), (n), sizeof(*(dst)) + \ + BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src +static inline void move_array(void *dst, const void *src, size_t n, size_t size) +{ + if (n) + memmove(dst, src, st_mult(size, n)); +} + /* * These functions help you allocate structs with flex arrays, and copy * the data directly into the array. For example, if you had: -- 2.13.3
[PATCH 1/2] add MOVE_ARRAY
Add MOVE_ARRAY to complement COPY_ARRAY, which was added in 60566cbb. It provides the same convenience, safety and support for NULL pointers as representations of empty arrays, just as a wrapper for memmove(3) instead of memcpy(3). Inspired-by: Martin LiskaSigned-off-by: Rene Scharfe --- git-compat-util.h | 8 1 file changed, 8 insertions(+) diff --git a/git-compat-util.h b/git-compat-util.h index 8a4a3f85e7..3266a71fb4 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -812,6 +812,14 @@ static inline void copy_array(void *dst, const void *src, size_t n, size_t size) memcpy(dst, src, st_mult(size, n)); } +#define MOVE_ARRAY(dst, src, n) move_array((dst), (src), (n), sizeof(*(dst)) + \ + BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src +static inline void move_array(void *dst, const void *src, size_t n, size_t size) +{ + if (n) + memmove(dst, src, st_mult(size, n)); +} + /* * These functions help you allocate structs with flex arrays, and copy * the data directly into the array. For example, if you had: -- 2.12.2