decorate: add clear_decoration() function

There's not currently any way to free the resources associated with a
decoration struct. As a result, we have several memory leaks which
cannot easily be plugged.

Let's add a "clear" function and make use of it in the example code of
t9004. This removes the only leak from that script, so we can mark it as
passing the leak sanitizer.

Curiously this leak is found only when running SANITIZE=leak with clang,
but not with gcc.  But it is a bog-standard leak: we allocate some
memory in a local variable struct, and then exit main() without
releasing it. I'm not sure why gcc doesn't find it. After this
patch, both compilers report it as leak-free.

Note that the clear function takes a callback to free the individual
entries. That's not needed for our example (which is just decorating
with ints), but will be for real callers.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2023-10-05 17:29:02 -04:00 committed by Junio C Hamano
parent 43c8a30d15
commit 771868243c
4 changed files with 29 additions and 0 deletions

View File

@ -81,3 +81,18 @@ void *lookup_decoration(struct decoration *n, const struct object *obj)
j = 0;
}
}
void clear_decoration(struct decoration *n, void (*free_cb)(void *))
{
if (free_cb) {
unsigned int i;
for (i = 0; i < n->size; i++) {
void *d = n->entries[i].decoration;
if (d)
free_cb(d);
}
}
FREE_AND_NULL(n->entries);
n->size = n->nr = 0;
}

View File

@ -58,4 +58,14 @@ void *add_decoration(struct decoration *n, const struct object *obj, void *decor
*/
void *lookup_decoration(struct decoration *n, const struct object *obj);
/*
* Clear all decoration entries, releasing any memory used by the structure.
* If free_cb is not NULL, it is called for every decoration value currently
* stored.
*
* After clearing, the decoration struct can be used again. The "name" field is
* retained.
*/
void clear_decoration(struct decoration *n, void (*free_cb)(void *));
#endif

View File

@ -72,5 +72,7 @@ int cmd__example_decorate(int argc UNUSED, const char **argv UNUSED)
if (objects_noticed != 2)
BUG("should have 2 objects");
clear_decoration(&n, NULL);
return 0;
}

View File

@ -1,6 +1,8 @@
#!/bin/sh
test_description='check that example code compiles and runs'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'decorate' '