1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "leak.h"
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "../memcheck.h"
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* We build this tree:
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           A
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /   \
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        B     C
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       / \   / \
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      D   E F   G
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Then we leak D and C-F-G.
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _Node {
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct _Node *l;
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct _Node *r;
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Padding ensures the structu is the same size on 32-bit and 64-bit
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // machines.
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char padding[16 - 2*sizeof(struct _Node*)];
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Node;
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownNode* mk(void)
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Node *x = malloc(sizeof(Node));
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   x->l = NULL;
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   x->r = NULL;
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return x;
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This is a definite root.
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownNode* t;
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid f(void)
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Building like this rather than "t = mk(mk(mk(NULL, NULL), ...)" seems to
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // help avoid leaving pointers on the stack to supposedly-leaked blocks.
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t       = mk();   // A
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->l    = mk();   // B
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->r    = mk();   // C  (48(16d,32i)/1 definitely leaked from here)
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->l->l = mk();   // D  (16/1 definitely leaked from here)
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->l->r = mk();   // E
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->r->l = mk();   // F
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->r->r = mk();   // G
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Sever B->D, leaking D
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->l->l = NULL;
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Sever A->C, leaking C-F-G
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   t->r = NULL;
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void)
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DECLARE_LEAK_COUNTERS;
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GET_INITIAL_LEAK_COUNTS;
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // See leak-cases.c for why we do the work in f().
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   f();
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GET_FINAL_LEAK_COUNTS;
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT_LEAK_COUNTS(stderr);
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
72