Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / memcheck / tests / leak_cpp_interior.cpp
bloba4b48245227ee271c3d89643c6d2c7c474483a1f
1 #define _GLIBCXX_USE_CXX11_ABI 0
2 #define __STDC_FORMAT_MACROS
3 #include <inttypes.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string>
9 #include <sstream>
10 #include "../memcheck.h"
11 // Derived from test provided by Timur Iskhodzhanov (bug 280271)
13 class MyClass
15 char m1;
16 int m2;
17 public:
18 ~MyClass()
19 { fprintf(stderr, "destruct MyClass\n");
23 // Two hierarchies using MI, one with no fields,
24 // the other one with some data.
25 struct Ae
27 virtual ~Ae()
28 { fprintf(stderr, "destruct Ae\n");
30 };
31 struct Be
33 virtual ~Be()
34 { fprintf(stderr, "destruct Be\n");
36 };
37 struct Ce : public Ae, public Be
39 virtual ~Ce()
40 { fprintf(stderr, "destruct Ce\n");
44 struct A
46 char a;
47 A()
48 { a = 'a';
50 virtual ~A()
51 { fprintf(stderr, "destruct A\n");
53 };
54 struct B
56 char b;
57 B()
58 { b = 'b';
60 virtual ~B()
61 { fprintf(stderr, "destruct B\n");
63 };
64 struct C : public A, public B
66 char c;
67 C()
68 { c = 'c';
70 virtual ~C()
71 { fprintf(stderr, "destruct C\n");
75 void* wrap64_malloc(int size)
77 uint64_t *p = (uint64_t*)malloc(size + 8);
78 *p = size;
79 ++p;
80 return p;
83 void wrap64_free(void *p)
85 uint64_t *p2 = (uint64_t*)p;
86 if (p2 == NULL)
87 return;
88 --p2;
89 free(p2);
92 std::string str;
93 std::string str2;
94 MyClass *ptr;
95 MyClass *ptr2;
96 Be *ptrBCe;
97 Ae *ptrACe;
98 B *ptrBC;
99 A *ptrAC;
100 void* ptr64;
102 char who_points_at_cmd[100];
104 void doit(void)
106 str = "Valgrind"; // interior ptr.
107 str2 = str;
108 ptr = new MyClass[3]; // interior ptr.
109 ptr64 = wrap64_malloc(23);
111 // prepare the who_points_at cmd we will run.
112 // Do it here to avoid having ptr or its exterior ptr kept in a register.
113 sprintf(who_points_at_cmd, "who_points_at %#" PRIxPTR " 20",
114 (uintptr_t) (char*)ptr - sizeof(void*));
116 ptr2 = new MyClass[0]; // "interior but exterior ptr".
117 // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked.
119 ptrBCe = new Ce; // interior ptr.
120 ptrACe = new Ce; // not an interior pointer.
121 ptrBC = new C; // interior ptr.
122 ptrAC = new C; // not an interior pointer.
125 str2 += " rocks (str2)\n"; // interior ptr.
129 int main() {
131 doit();
132 (void) VALGRIND_MONITOR_COMMAND("v.set log_output");
134 fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n");
135 VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data.
137 // Check individually each heuristic
138 fprintf(stderr, "leak_check summary heuristics multipleinheritance\n");
139 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance");
140 fprintf(stderr, "leak_check summary any heuristics newarray\n");
141 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray");
142 fprintf(stderr, "leak_check summary heuristics length64\n");
143 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics length64");
144 fprintf(stderr, "leak_check summary heuristics stdstring\n");
145 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring");
147 // check all and none
148 fprintf(stderr, "leak_check summary heuristics multipleinheritance,newarray,stdstring,length64\n");
149 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance,newarray,stdstring,length64");
150 fprintf(stderr, "leak_check summary heuristics all\n");
151 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics all");
152 fprintf(stderr, "leak_check summary heuristics none\n");
153 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics none");
155 // Test the who_points_at when the block is pointed to with an interior ptr.
156 (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd);
158 delete [] ptr;
159 delete [] ptr2;
160 delete ptrBCe;
161 delete ptrACe;
162 delete ptrBC;
163 delete ptrAC;
164 wrap64_free(ptr64);
165 fprintf(stderr, "Finished!\n");
166 return 0;