1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "leak.h"
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "../memcheck.h"
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct n {
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct n *l;
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct n *r;
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        // This ensures it's the same size on 32-bit and 64-bit platforms.
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        char padding[ 2 * (8 - sizeof(struct n*)) ];
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct n *mk(struct n *l, struct n *r)
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct n *n = malloc(sizeof(struct n));
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	n->l = l;
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	n->r = r;
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return n;
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct n *mkcycle()
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	register struct n *a, *b, *c;
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	a = mk(0,0);
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	b = mk(a,0);
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c = mk(b,0);
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	a->l = c;
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return a;
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main()
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	DECLARE_LEAK_COUNTERS;
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct n *volatile c1, *volatile c2;
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        GET_INITIAL_LEAK_COUNTS;
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* two simple cycles */
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = mkcycle();
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c2 = mkcycle();
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = c2 = 0;
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* one cycle linked to another */
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = mkcycle();
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c2 = mkcycle();
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* This is to make sure we end up merging cliques; see
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   mc_leakcheck.c */
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (c1 < c2)
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		c2->r = c1;
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		c1->r = c2;
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = c2 = 0;
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* two linked cycles */
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = mkcycle();
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c2 = mkcycle();
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1->r = c2;
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c2->r = c1;
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c1 = c2 = 0;
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	CLEAR_CALLER_SAVED_REGS;
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	GET_FINAL_LEAK_COUNTS;
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	PRINT_LEAK_COUNTS(stderr);
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
79