Browse Source

hashtable: fix traverse typesafety.

Rusty Russell 16 years ago
parent
commit
a447839504

+ 12 - 11
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);

+ 32 - 0
ccan/hashtable/test/compile_fail-traverse-arg1.c

@@ -0,0 +1,32 @@
+#include <ccan/hashtable/hashtable.h>
+#include <ccan/hashtable/hashtable.c>
+#include <stdlib.h>
+
+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;
+}

+ 31 - 0
ccan/hashtable/test/compile_fail-traverse-arg2.c

@@ -0,0 +1,31 @@
+#include <ccan/hashtable/hashtable.h>
+#include <ccan/hashtable/hashtable.c>
+#include <stdlib.h>
+
+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;
+}

+ 49 - 0
ccan/hashtable/test/compile_ok-traverse.c

@@ -0,0 +1,49 @@
+#include <ccan/hashtable/hashtable.h>
+#include <ccan/hashtable/hashtable.c>
+
+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;
+}