]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/inner-pointer.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / Analysis / inner-pointer.cpp
1 //RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s -analyzer-output=text -verify
2
3 namespace std {
4
5 typedef int size_type;
6
7 template <typename CharT>
8 class basic_string {
9 public:
10   basic_string();
11   basic_string(const CharT *s);
12
13   ~basic_string();
14   void clear();
15
16   basic_string &operator=(const basic_string &str);
17   basic_string &operator+=(const basic_string &str);
18
19   const CharT *c_str() const;
20   const CharT *data() const;
21   CharT *data();
22
23   basic_string &append(size_type count, CharT ch);
24   basic_string &assign(size_type count, CharT ch);
25   basic_string &erase(size_type index, size_type count);
26   basic_string &insert(size_type index, size_type count, CharT ch);
27   basic_string &replace(size_type pos, size_type count, const basic_string &str);
28   void pop_back();
29   void push_back(CharT ch);
30   void reserve(size_type new_cap);
31   void resize(size_type count);
32   void shrink_to_fit();
33   void swap(basic_string &other);
34 };
35
36 typedef basic_string<char> string;
37 typedef basic_string<wchar_t> wstring;
38 typedef basic_string<char16_t> u16string;
39 typedef basic_string<char32_t> u32string;
40
41 } // end namespace std
42
43 void consume(const char *) {}
44 void consume(const wchar_t *) {}
45 void consume(const char16_t *) {}
46 void consume(const char32_t *) {}
47
48 void deref_after_scope_char(bool cond) {
49   const char *c, *d;
50   {
51     std::string s;
52     c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
53     d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
54   }                // expected-note {{Inner pointer invalidated by call to destructor}}
55   // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
56   std::string s;
57   const char *c2 = s.c_str();
58   if (cond) {
59     // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
60     // expected-note@-2 {{Taking true branch}}
61     // expected-note@-3 {{Assuming 'cond' is 0}}
62     // expected-note@-4 {{Taking false branch}}
63     consume(c); // expected-warning {{Use of memory after it is freed}}
64     // expected-note@-1 {{Use of memory after it is freed}}
65   } else {
66     consume(d); // expected-warning {{Use of memory after it is freed}}
67     // expected-note@-1 {{Use of memory after it is freed}}
68   }
69 }
70
71 void deref_after_scope_char_data_non_const() {
72   char *c;
73   {
74     std::string s;
75     c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
76   }               // expected-note {{Inner pointer invalidated by call to destructor}}
77   std::string s;
78   char *c2 = s.data();
79   consume(c); // expected-warning {{Use of memory after it is freed}}
80   // expected-note@-1 {{Use of memory after it is freed}}
81 }
82
83 void deref_after_scope_wchar_t(bool cond) {
84   const wchar_t *c, *d;
85   {
86     std::wstring s;
87     c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
88     d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
89   }                // expected-note {{Inner pointer invalidated by call to destructor}}
90   // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
91   std::wstring s;
92   const wchar_t *c2 = s.c_str();
93   if (cond) {
94     // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
95     // expected-note@-2 {{Taking true branch}}
96     // expected-note@-3 {{Assuming 'cond' is 0}}
97     // expected-note@-4 {{Taking false branch}}
98     consume(c); // expected-warning {{Use of memory after it is freed}}
99     // expected-note@-1 {{Use of memory after it is freed}}
100   } else {
101     consume(d); // expected-warning {{Use of memory after it is freed}}
102     // expected-note@-1 {{Use of memory after it is freed}}
103   }
104 }
105
106 void deref_after_scope_char16_t_cstr() {
107   const char16_t *c16;
108   {
109     std::u16string s16;
110     c16 = s16.c_str(); // expected-note {{Dangling inner pointer obtained here}}
111   }                    // expected-note {{Inner pointer invalidated by call to destructor}}
112   std::u16string s16;
113   const char16_t *c16_2 = s16.c_str();
114   consume(c16); // expected-warning {{Use of memory after it is freed}}
115   // expected-note@-1 {{Use of memory after it is freed}}
116 }
117
118 void deref_after_scope_char32_t_data() {
119   const char32_t *c32;
120   {
121     std::u32string s32;
122     c32 = s32.data(); // expected-note {{Dangling inner pointer obtained here}}
123   }                   // expected-note {{Inner pointer invalidated by call to destructor}}
124   std::u32string s32;
125   const char32_t *c32_2 = s32.data();
126   consume(c32); // expected-warning {{Use of memory after it is freed}}
127   // expected-note@-1 {{Use of memory after it is freed}}
128 }
129
130 void multiple_symbols(bool cond) {
131   const char *c1, *d1;
132   {
133     std::string s1;
134     c1 = s1.c_str(); // expected-note {{Dangling inner pointer obtained here}}
135     d1 = s1.data();  // expected-note {{Dangling inner pointer obtained here}}
136     const char *local = s1.c_str();
137     consume(local); // no-warning
138   }                 // expected-note {{Inner pointer invalidated by call to destructor}}
139   // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
140   std::string s2;
141   const char *c2 = s2.c_str();
142   if (cond) {
143     // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
144     // expected-note@-2 {{Taking true branch}}
145     // expected-note@-3 {{Assuming 'cond' is 0}}
146     // expected-note@-4 {{Taking false branch}}
147     consume(c1); // expected-warning {{Use of memory after it is freed}}
148     // expected-note@-1 {{Use of memory after it is freed}}
149   } else {
150     consume(d1); // expected-warning {{Use of memory after it is freed}}
151   }              // expected-note@-1 {{Use of memory after it is freed}}
152 }
153
154 void deref_after_equals() {
155   const char *c;
156   std::string s = "hello";
157   c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
158   s = "world";   // expected-note {{Inner pointer invalidated by call to 'operator='}}
159   consume(c);    // expected-warning {{Use of memory after it is freed}}
160   // expected-note@-1 {{Use of memory after it is freed}}
161 }
162
163 void deref_after_plus_equals() {
164   const char *c;
165   std::string s = "hello";
166   c = s.data();  // expected-note {{Dangling inner pointer obtained here}}
167   s += " world"; // expected-note {{Inner pointer invalidated by call to 'operator+='}}
168   consume(c);    // expected-warning {{Use of memory after it is freed}}
169   // expected-note@-1 {{Use of memory after it is freed}}
170 }
171
172 void deref_after_clear() {
173   const char *c;
174   std::string s;
175   c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
176   s.clear();     // expected-note {{Inner pointer invalidated by call to 'clear'}}
177   consume(c);    // expected-warning {{Use of memory after it is freed}}
178   // expected-note@-1 {{Use of memory after it is freed}}
179 }
180
181 void deref_after_append() {
182   const char *c;
183   std::string s = "hello";
184   c = s.c_str();    // expected-note {{Dangling inner pointer obtained here}}
185   s.append(2, 'x'); // expected-note {{Inner pointer invalidated by call to 'append'}}
186   consume(c);       // expected-warning {{Use of memory after it is freed}}
187   // expected-note@-1 {{Use of memory after it is freed}}
188 }
189
190 void deref_after_assign() {
191   const char *c;
192   std::string s;
193   c = s.data();     // expected-note {{Dangling inner pointer obtained here}}
194   s.assign(4, 'a'); // expected-note {{Inner pointer invalidated by call to 'assign'}}
195   consume(c);       // expected-warning {{Use of memory after it is freed}}
196   // expected-note@-1 {{Use of memory after it is freed}}
197 }
198
199 void deref_after_erase() {
200   const char *c;
201   std::string s = "hello";
202   c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
203   s.erase(0, 2); // expected-note {{Inner pointer invalidated by call to 'erase'}}
204   consume(c);    // expected-warning {{Use of memory after it is freed}}
205   // expected-note@-1 {{Use of memory after it is freed}}
206 }
207
208 void deref_after_insert() {
209   const char *c;
210   std::string s = "ello";
211   c = s.c_str();       // expected-note {{Dangling inner pointer obtained here}}
212   s.insert(0, 1, 'h'); // expected-note {{Inner pointer invalidated by call to 'insert'}}
213   consume(c);          // expected-warning {{Use of memory after it is freed}}
214   // expected-note@-1 {{Use of memory after it is freed}}
215 }
216
217 void deref_after_replace() {
218   const char *c;
219   std::string s = "hello world";
220   c = s.c_str();             // expected-note {{Dangling inner pointer obtained here}}
221   s.replace(6, 5, "string"); // expected-note {{Inner pointer invalidated by call to 'replace'}}
222   consume(c);                // expected-warning {{Use of memory after it is freed}}
223   // expected-note@-1 {{Use of memory after it is freed}}
224 }
225
226 void deref_after_pop_back() {
227   const char *c;
228   std::string s;
229   c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
230   s.pop_back();  // expected-note {{Inner pointer invalidated by call to 'pop_back'}}
231   consume(c);    // expected-warning {{Use of memory after it is freed}}
232   // expected-note@-1 {{Use of memory after it is freed}}
233 }
234
235 void deref_after_push_back() {
236   const char *c;
237   std::string s;
238   c = s.data();     // expected-note {{Dangling inner pointer obtained here}}
239   s.push_back('c'); // expected-note {{Inner pointer invalidated by call to 'push_back'}}
240   consume(c);       // expected-warning {{Use of memory after it is freed}}
241   // expected-note@-1 {{Use of memory after it is freed}}
242 }
243
244 void deref_after_reserve() {
245   const char *c;
246   std::string s;
247   c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
248   s.reserve(5);  // expected-note {{Inner pointer invalidated by call to 'reserve'}}
249   consume(c);    // expected-warning {{Use of memory after it is freed}}
250   // expected-note@-1 {{Use of memory after it is freed}}
251 }
252
253 void deref_after_resize() {
254   const char *c;
255   std::string s;
256   c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
257   s.resize(5);  // expected-note {{Inner pointer invalidated by call to 'resize'}}
258   consume(c);   // expected-warning {{Use of memory after it is freed}}
259   // expected-note@-1 {{Use of memory after it is freed}}
260 }
261
262 void deref_after_shrink_to_fit() {
263   const char *c;
264   std::string s;
265   c = s.data();      // expected-note {{Dangling inner pointer obtained here}}
266   s.shrink_to_fit(); // expected-note {{Inner pointer invalidated by call to 'shrink_to_fit'}}
267   consume(c);        // expected-warning {{Use of memory after it is freed}}
268   // expected-note@-1 {{Use of memory after it is freed}}
269 }
270
271 void deref_after_swap() {
272   const char *c;
273   std::string s1, s2;
274   c = s1.data(); // expected-note {{Dangling inner pointer obtained here}}
275   s1.swap(s2);   // expected-note {{Inner pointer invalidated by call to 'swap'}}
276   consume(c);    // expected-warning {{Use of memory after it is freed}}
277   // expected-note@-1 {{Use of memory after it is freed}}
278 }
279
280 void deref_after_scope_ok(bool cond) {
281   const char *c, *d;
282   std::string s;
283   {
284     c = s.c_str();
285     d = s.data();
286   }
287   if (cond)
288     consume(c); // no-warning
289   else
290     consume(d); // no-warning
291 }