summaryrefslogtreecommitdiff
path: root/contrib/coccinelle
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/coccinelle')
-rw-r--r--contrib/coccinelle/array.cocci82
-rw-r--r--contrib/coccinelle/tests/free.c11
-rw-r--r--contrib/coccinelle/tests/free.res9
-rw-r--r--contrib/coccinelle/tests/unused.c82
-rw-r--r--contrib/coccinelle/tests/unused.res45
-rw-r--r--contrib/coccinelle/unused.cocci43
6 files changed, 230 insertions, 42 deletions
diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci
index 9a4f00cb1b..aa75937950 100644
--- a/contrib/coccinelle/array.cocci
+++ b/contrib/coccinelle/array.cocci
@@ -1,60 +1,58 @@
@@
-expression dst, src, n, E;
+type T;
+T *dst_ptr;
+T *src_ptr;
+expression n;
@@
- memcpy(dst, src, n * sizeof(
-- E[...]
-+ *(E)
- ))
+- memcpy(dst_ptr, src_ptr, (n) * \( sizeof(T)
+- \| sizeof(*(dst_ptr))
+- \| sizeof(*(src_ptr))
+- \| sizeof(dst_ptr[...])
+- \| sizeof(src_ptr[...])
+- \) )
++ COPY_ARRAY(dst_ptr, src_ptr, n)
@@
type T;
-T *ptr;
-T[] arr;
-expression E, n;
+T *dst_ptr;
+T[] src_arr;
+expression 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)
- )
-)
+- memcpy(dst_ptr, src_arr, (n) * \( sizeof(T)
+- \| sizeof(*(dst_ptr))
+- \| sizeof(*(src_arr))
+- \| sizeof(dst_ptr[...])
+- \| sizeof(src_arr[...])
+- \) )
++ COPY_ARRAY(dst_ptr, src_arr, n)
@@
type T;
-T *dst_ptr;
+T[] dst_arr;
T *src_ptr;
+expression n;
+@@
+- memcpy(dst_arr, src_ptr, (n) * \( sizeof(T)
+- \| sizeof(*(dst_arr))
+- \| sizeof(*(src_ptr))
+- \| sizeof(dst_arr[...])
+- \| sizeof(src_ptr[...])
+- \) )
++ COPY_ARRAY(dst_arr, src_ptr, n)
+
+@@
+type T;
T[] dst_arr;
T[] src_arr;
expression 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))
+- memcpy(dst_arr, src_arr, (n) * \( sizeof(T)
+- \| sizeof(*(dst_arr))
+- \| sizeof(*(src_arr))
+- \| sizeof(dst_arr[...])
+- \| sizeof(src_arr[...])
+- \) )
+ COPY_ARRAY(dst_arr, src_arr, n)
-)
@@
type T;
diff --git a/contrib/coccinelle/tests/free.c b/contrib/coccinelle/tests/free.c
new file mode 100644
index 0000000000..96d4abc0c7
--- /dev/null
+++ b/contrib/coccinelle/tests/free.c
@@ -0,0 +1,11 @@
+int use_FREE_AND_NULL(int *v)
+{
+ free(*v);
+ *v = NULL;
+}
+
+int need_no_if(int *v)
+{
+ if (v)
+ free(v);
+}
diff --git a/contrib/coccinelle/tests/free.res b/contrib/coccinelle/tests/free.res
new file mode 100644
index 0000000000..f90fd9f48e
--- /dev/null
+++ b/contrib/coccinelle/tests/free.res
@@ -0,0 +1,9 @@
+int use_FREE_AND_NULL(int *v)
+{
+ FREE_AND_NULL(*v);
+}
+
+int need_no_if(int *v)
+{
+ free(v);
+}
diff --git a/contrib/coccinelle/tests/unused.c b/contrib/coccinelle/tests/unused.c
new file mode 100644
index 0000000000..8294d734ba
--- /dev/null
+++ b/contrib/coccinelle/tests/unused.c
@@ -0,0 +1,82 @@
+void test_strbuf(void)
+{
+ struct strbuf sb1 = STRBUF_INIT;
+ struct strbuf sb2 = STRBUF_INIT;
+ struct strbuf sb3 = STRBUF_INIT;
+ struct strbuf sb4 = STRBUF_INIT;
+ struct strbuf sb5;
+ struct strbuf sb6 = { 0 };
+ struct strbuf sb7 = STRBUF_INIT;
+ struct strbuf sb8 = STRBUF_INIT;
+ struct strbuf *sp1;
+ struct strbuf *sp2;
+ struct strbuf *sp3;
+ struct strbuf *sp4 = xmalloc(sizeof(struct strbuf));
+ struct strbuf *sp5 = xmalloc(sizeof(struct strbuf));
+ struct strbuf *sp6 = xmalloc(sizeof(struct strbuf));
+ struct strbuf *sp7;
+
+ strbuf_init(&sb5, 0);
+ strbuf_init(sp1, 0);
+ strbuf_init(sp2, 0);
+ strbuf_init(sp3, 0);
+ strbuf_init(sp4, 0);
+ strbuf_init(sp5, 0);
+ strbuf_init(sp6, 0);
+ strbuf_init(sp7, 0);
+ sp7 = xmalloc(sizeof(struct strbuf));
+
+ use_before(&sb3);
+ use_as_str("%s", sb7.buf);
+ use_as_str("%s", sp1->buf);
+ use_as_str("%s", sp6->buf);
+ pass_pp(&sp3);
+
+ strbuf_release(&sb1);
+ strbuf_reset(&sb2);
+ strbuf_release(&sb3);
+ strbuf_release(&sb4);
+ strbuf_release(&sb5);
+ strbuf_release(&sb6);
+ strbuf_release(&sb7);
+ strbuf_release(sp1);
+ strbuf_release(sp2);
+ strbuf_release(sp3);
+ strbuf_release(sp4);
+ strbuf_release(sp5);
+ strbuf_release(sp6);
+ strbuf_release(sp7);
+
+ use_after(&sb4);
+
+ if (when_strict())
+ return;
+ strbuf_release(&sb8);
+}
+
+void test_other(void)
+{
+ struct string_list l = STRING_LIST_INIT_DUP;
+ struct strbuf sb = STRBUF_INIT;
+
+ string_list_clear(&l, 0);
+ string_list_clear(&sb, 0);
+}
+
+void test_worktrees(void)
+{
+ struct worktree **w1 = get_worktrees();
+ struct worktree **w2 = get_worktrees();
+ struct worktree **w3;
+ struct worktree **w4;
+
+ w3 = get_worktrees();
+ w4 = get_worktrees();
+
+ use_it(w4);
+
+ free_worktrees(w1);
+ free_worktrees(w2);
+ free_worktrees(w3);
+ free_worktrees(w4);
+}
diff --git a/contrib/coccinelle/tests/unused.res b/contrib/coccinelle/tests/unused.res
new file mode 100644
index 0000000000..6d3e745683
--- /dev/null
+++ b/contrib/coccinelle/tests/unused.res
@@ -0,0 +1,45 @@
+void test_strbuf(void)
+{
+ struct strbuf sb3 = STRBUF_INIT;
+ struct strbuf sb4 = STRBUF_INIT;
+ struct strbuf sb7 = STRBUF_INIT;
+ struct strbuf *sp1;
+ struct strbuf *sp3;
+ struct strbuf *sp6 = xmalloc(sizeof(struct strbuf));
+ strbuf_init(sp1, 0);
+ strbuf_init(sp3, 0);
+ strbuf_init(sp6, 0);
+
+ use_before(&sb3);
+ use_as_str("%s", sb7.buf);
+ use_as_str("%s", sp1->buf);
+ use_as_str("%s", sp6->buf);
+ pass_pp(&sp3);
+
+ strbuf_release(&sb3);
+ strbuf_release(&sb4);
+ strbuf_release(&sb7);
+ strbuf_release(sp1);
+ strbuf_release(sp3);
+ strbuf_release(sp6);
+
+ use_after(&sb4);
+
+ if (when_strict())
+ return;
+}
+
+void test_other(void)
+{
+}
+
+void test_worktrees(void)
+{
+ struct worktree **w4;
+
+ w4 = get_worktrees();
+
+ use_it(w4);
+
+ free_worktrees(w4);
+}
diff --git a/contrib/coccinelle/unused.cocci b/contrib/coccinelle/unused.cocci
new file mode 100644
index 0000000000..d84046f82e
--- /dev/null
+++ b/contrib/coccinelle/unused.cocci
@@ -0,0 +1,43 @@
+// This rule finds sequences of "unused" declerations and uses of a
+// variable, where "unused" is defined to include only calling the
+// equivalent of alloc, init & free functions on the variable.
+@@
+type T;
+identifier I;
+// STRBUF_INIT, but also e.g. STRING_LIST_INIT_DUP (so no anchoring)
+constant INIT_MACRO =~ "_INIT";
+identifier MALLOC1 =~ "^x?[mc]alloc$";
+identifier INIT_ASSIGN1 =~ "^get_worktrees$";
+identifier INIT_CALL1 =~ "^[a-z_]*_init$";
+identifier REL1 =~ "^[a-z_]*_(release|reset|clear|free)$";
+identifier REL2 =~ "^(release|clear|free)_[a-z_]*$";
+@@
+
+(
+- T I;
+|
+- T I = { 0 };
+|
+- T I = INIT_MACRO;
+|
+- T I = MALLOC1(...);
+|
+- T I = INIT_ASSIGN1(...);
+)
+
+<... when != \( I \| &I \)
+(
+- \( INIT_CALL1 \)( \( I \| &I \), ...);
+|
+- I = \( INIT_ASSIGN1 \)(...);
+|
+- I = MALLOC1(...);
+)
+...>
+
+(
+- \( REL1 \| REL2 \)( \( I \| &I \), ...);
+|
+- \( REL1 \| REL2 \)( \( &I \| I \) );
+)
+ ... when != \( I \| &I \)