--- /dev/null
+#include <ccan/tal/link/link.c>
+#include <ccan/tap/tap.h>
+#include <stdlib.h>
+#include <err.h>
+
+static unsigned int destroy_count = 0;
+static void destroy_obj(void *obj)
+{
+ destroy_count++;
+}
+
+int main(int argc, char *argv[])
+{
+ char *linkable, *p1, *p2, *p3;
+ void **voidpp;
+
+ plan_tests(23);
+
+ linkable = tal(NULL, char);
+ ok1(tal_linkable(linkable) == linkable);
+ ok1(tal_add_destructor(linkable, destroy_obj));
+ /* First, free it immediately. */
+ tal_free(linkable);
+ ok1(destroy_count == 1);
+
+ /* Now create and remove a single link. */
+ linkable = tal_linkable(tal(NULL, char));
+ ok1(tal_add_destructor(linkable, destroy_obj));
+ ok1(p1 = tal_link(NULL, linkable));
+ ok1(p1 == linkable);
+ tal_delink(NULL, linkable);
+ ok1(destroy_count == 2);
+
+ /* Two links.*/
+ linkable = tal_linkable(tal(NULL, char));
+ ok1(tal_add_destructor(linkable, destroy_obj));
+ ok1(p1 = tal_link(NULL, linkable));
+ ok1(p1 == linkable);
+ ok1(p2 = tal_link(NULL, linkable));
+ ok1(p2 == linkable);
+ tal_delink(NULL, linkable);
+ tal_delink(NULL, linkable);
+ ok1(destroy_count == 3);
+
+ /* Three links.*/
+ linkable = tal_linkable(tal(NULL, char));
+ ok1(tal_add_destructor(linkable, destroy_obj));
+ ok1(p1 = tal_link(NULL, linkable));
+ ok1(p1 == linkable);
+ ok1(p2 = tal_link(NULL, linkable));
+ ok1(p2 == linkable);
+ ok1(p3 = tal_link(NULL, linkable));
+ ok1(p3 == linkable);
+ tal_delink(NULL, linkable);
+ tal_delink(NULL, linkable);
+ tal_delink(NULL, linkable);
+ ok1(destroy_count == 4);
+
+ /* Now, indirectly. */
+ voidpp = tal(NULL, void *);
+ linkable = tal_linkable(tal(NULL, char));
+ ok1(tal_add_destructor(linkable, destroy_obj));
+/* Suppress gratuitous warning with tests_compile_without_features */
+#if HAVE_STATEMENT_EXPR
+ tal_link(voidpp, linkable);
+#else
+ (void)tal_link(voidpp, linkable);
+#endif
+ tal_free(voidpp);
+ ok1(destroy_count == 5);
+
+ return exit_status();
+}