#include <stdio.h>
#include <stdlib.h>
#include "leak.h"
#include "../memcheck.h"

struct n {
	struct n *l;
	struct n *r;
        // This ensures it's the same size on 32-bit and 64-bit platforms.
        char padding[ 2 * (8 - sizeof(struct n*)) ];
};

struct n *mk(struct n *l, struct n *r)
{
	struct n *n = malloc(sizeof(struct n));
	n->l = l;
	n->r = r;

	return n;
}

static struct n *mkcycle()
{
	register struct n *a, *b, *c;

	a = mk(0,0);
	b = mk(a,0);
	c = mk(b,0);
	a->l = c;

	return a;
}


int main()
{
	DECLARE_LEAK_COUNTERS;

	struct n *volatile c1, *volatile c2;

        GET_INITIAL_LEAK_COUNTS;

	/* two simple cycles */
	c1 = mkcycle();
	c2 = mkcycle();

	c1 = c2 = 0;

	/* one cycle linked to another */
	c1 = mkcycle();
	c2 = mkcycle();

	/* This is to make sure we end up merging cliques; see
	   mc_leakcheck.c */
	if (c1 < c2)
		c2->r = c1;
	else
		c1->r = c2;

	c1 = c2 = 0;

	/* two linked cycles */
	c1 = mkcycle();
	c2 = mkcycle();

	c1->r = c2;
	c2->r = c1;

	c1 = c2 = 0;

	CLEAR_CALLER_SAVED_REGS;

	GET_FINAL_LEAK_COUNTS;

	PRINT_LEAK_COUNTS(stderr);

	return 0;
}