1#include <stdio.h>
2#include <unistd.h>
3#include <string>
4#include <sstream>
5#include "../memcheck.h"
6// Derived from test provided by Timur Iskhodzhanov (bug 280271)
7
8class MyClass
9{
10public:
11   ~MyClass()
12   { fprintf(stderr, "destruct MyClass\n");
13   }
14};
15
16// Two hierarchies using MI, one with no fields,
17// the other one with some data.
18struct Ae
19{
20   virtual ~Ae()
21   { fprintf(stderr, "destruct Ae\n");
22   }
23};
24struct Be
25{
26   virtual ~Be()
27   { fprintf(stderr, "destruct Be\n");
28   }
29};
30struct Ce : public Ae, public Be
31{
32   virtual ~Ce()
33   { fprintf(stderr, "destruct Ce\n");
34   }
35};
36
37struct A
38{
39   char a;
40   A()
41   { a = 'a';
42   }
43   virtual ~A()
44   { fprintf(stderr, "destruct A\n");
45   }
46};
47struct B
48{
49   char b;
50   B()
51   { b = 'b';
52   }
53   virtual ~B()
54   { fprintf(stderr, "destruct B\n");
55   }
56};
57struct C : public A, public B
58{
59   char c;
60   C()
61   { c = 'c';
62   }
63   virtual ~C()
64   { fprintf(stderr, "destruct C\n");
65   }
66};
67
68std::string str;
69std::string str2;
70MyClass *ptr;
71MyClass *ptr2;
72Be *ptrBCe;
73Ae *ptrACe;
74B *ptrBC;
75A *ptrAC;
76
77char who_points_at_cmd[100];
78
79void doit(void)
80{
81  str = "Valgrind"; // interior ptr.
82  str2 = str;
83  ptr = new MyClass[3]; // interior ptr.
84
85  // prepare the who_points_at cmd we will run.
86  // Do it here to avoid having ptr or its exterior ptr kept in a register.
87  sprintf(who_points_at_cmd, "who_points_at %p 20", (char*)ptr - sizeof(void*));
88
89  ptr2 = new MyClass[0]; // "interior but exterior ptr".
90  // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked.
91
92  ptrBCe = new Ce;  // interior ptr.
93  ptrACe = new Ce;  // not an interior pointer.
94  ptrBC = new C;  // interior ptr.
95  ptrAC = new C;  // not an interior pointer.
96
97
98  str2 += " rocks (str2)\n"; // interior ptr.
99}
100
101
102int main() {
103
104   doit();
105   (void) VALGRIND_MONITOR_COMMAND("v.set log_output");
106
107   fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n");
108   VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data.
109
110   // Check individually each heuristic
111   fprintf(stderr, "leak_check summary heuristics multipleinheritance\n");
112   (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance");
113   fprintf(stderr, "leak_check summary any heuristics newarray\n");
114   (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray");
115   fprintf(stderr, "leak_check summary heuristics stdstring\n");
116   (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring");
117
118   // Test the who_points_at when the block is pointed to with an interior ptr.
119   (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd);
120
121   delete [] ptr;
122   delete [] ptr2;
123   delete ptrBCe;
124   delete ptrACe;
125   delete ptrBC;
126   delete ptrAC;
127   fprintf(stderr, "Finished!\n");
128   return 0;
129}
130
131