Re: [PATCH 1/2] add MOVE_ARRAY

2017-07-16 Thread Jeff King
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

2017-07-15 Thread René Scharfe
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

2017-04-07 Thread René Scharfe
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 Liska 
Signed-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