From a447839504042d706b30c347a17150813ecadd4a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 7 Jun 2010 14:00:22 +0930 Subject: [PATCH] hashtable: fix traverse typesafety. --- ccan/hashtable/hashtable.h | 23 ++++----- .../test/compile_fail-traverse-arg1.c | 32 ++++++++++++ .../test/compile_fail-traverse-arg2.c | 31 ++++++++++++ ccan/hashtable/test/compile_ok-traverse.c | 49 +++++++++++++++++++ 4 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 ccan/hashtable/test/compile_fail-traverse-arg1.c create mode 100644 ccan/hashtable/test/compile_fail-traverse-arg2.c create mode 100644 ccan/hashtable/test/compile_ok-traverse.c diff --git a/ccan/hashtable/hashtable.h b/ccan/hashtable/hashtable.h index 155ad3fc..7aa27fb3 100644 --- a/ccan/hashtable/hashtable.h +++ b/ccan/hashtable/hashtable.h @@ -73,17 +73,18 @@ bool hashtable_del(struct hashtable *ht, unsigned long hash, const void *p); */ #define hashtable_traverse(ht, type, cb, cbarg) \ _hashtable_traverse(ht, cast_if_type(bool (*)(void *, void *), \ - cast_if_any(bool (*)(void *, \ - void *), (cb), \ - bool (*)(const type *, \ - const typeof(*cbarg) *), \ - bool (*)(type *, \ - const typeof(*cbarg) *), \ - bool (*)(const type *, \ - typeof(*cbarg) *)), \ - bool (*)(type *, \ - typeof(*cbarg) *)), \ - cbarg) + cast_if_any(bool (*)(void *, \ + void *), \ + (cb), (cb), \ + bool (*)(const type *, \ + const typeof(*cbarg) *), \ + bool (*)(type *, \ + const typeof(*cbarg) *), \ + bool (*)(const type *, \ + typeof(*cbarg) *)), \ + (cb), \ + bool (*)(type *, typeof(*cbarg) *)), \ + (cbarg)) void _hashtable_traverse(struct hashtable *ht, bool (*cb)(void *p, void *cbarg), void *cbarg); diff --git a/ccan/hashtable/test/compile_fail-traverse-arg1.c b/ccan/hashtable/test/compile_fail-traverse-arg1.c new file mode 100644 index 00000000..470d425c --- /dev/null +++ b/ccan/hashtable/test/compile_fail-traverse-arg1.c @@ -0,0 +1,32 @@ +#include +#include +#include + +struct foo { + int i; +}; + +struct bar { + int i; +}; + +static bool fn_bar_bar( +#ifdef FAIL + struct bar * +#else + struct foo * +#endif + foo, + struct bar *bar) +{ + return true; +} + +int main(void) +{ + struct hashtable *ht = NULL; + struct bar *bar = NULL; + + hashtable_traverse(ht, struct foo, fn_bar_bar, bar); + return 0; +} diff --git a/ccan/hashtable/test/compile_fail-traverse-arg2.c b/ccan/hashtable/test/compile_fail-traverse-arg2.c new file mode 100644 index 00000000..5f6ea36a --- /dev/null +++ b/ccan/hashtable/test/compile_fail-traverse-arg2.c @@ -0,0 +1,31 @@ +#include +#include +#include + +struct foo { + int i; +}; + +struct bar { + int i; +}; + +static bool fn_foo_foo(struct foo *foo, +#ifdef FAIL + struct foo * +#else + struct bar * +#endif + bar) +{ + return true; +} + +int main(void) +{ + struct hashtable *ht = NULL; + struct bar *bar = NULL; + + hashtable_traverse(ht, struct foo, fn_foo_foo, bar); + return 0; +} diff --git a/ccan/hashtable/test/compile_ok-traverse.c b/ccan/hashtable/test/compile_ok-traverse.c new file mode 100644 index 00000000..365180d4 --- /dev/null +++ b/ccan/hashtable/test/compile_ok-traverse.c @@ -0,0 +1,49 @@ +#include +#include + +struct foo { + int i; +}; + +struct bar { + int i; +}; + +static bool fn_foo_bar(struct foo *foo, struct bar *bar) +{ + return true; +} + +static bool fn_const_foo_bar(const struct foo *foo, struct bar *bar) +{ + return true; +} + +static bool fn_foo_const_bar(struct foo *foo, const struct bar *bar) +{ + return true; +} + +static bool fn_const_foo_const_bar(const struct foo *foo, + const struct bar *bar) +{ + return true; +} + +static bool fn_void_void(void *foo, void *bar) +{ + return true; +} + +int main(void) +{ + struct hashtable *ht = NULL; + struct bar *bar = NULL; + + hashtable_traverse(ht, struct foo, fn_foo_bar, bar); + hashtable_traverse(ht, struct foo, fn_const_foo_bar, bar); + hashtable_traverse(ht, struct foo, fn_foo_const_bar, bar); + hashtable_traverse(ht, struct foo, fn_const_foo_const_bar, bar); + hashtable_traverse(ht, struct foo, fn_void_void, bar); + return 0; +} -- 2.39.2