1 //RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s -analyzer-output=text -verify
7 template <typename CharT>
11 basic_string(const CharT *s);
16 basic_string &operator=(const basic_string &str);
17 basic_string &operator+=(const basic_string &str);
19 const CharT *c_str() const;
20 const CharT *data() const;
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);
29 void push_back(CharT ch);
30 void reserve(size_type new_cap);
31 void resize(size_type count);
33 void swap(basic_string &other);
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;
41 } // end namespace std
43 void consume(const char *) {}
44 void consume(const wchar_t *) {}
45 void consume(const char16_t *) {}
46 void consume(const char32_t *) {}
48 void deref_after_scope_char(bool cond) {
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}}
57 const char *c2 = s.c_str();
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}}
66 consume(d); // expected-warning {{Use of memory after it is freed}}
67 // expected-note@-1 {{Use of memory after it is freed}}
71 void deref_after_scope_char_data_non_const() {
75 c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
76 } // expected-note {{Inner pointer invalidated by call to destructor}}
79 consume(c); // expected-warning {{Use of memory after it is freed}}
80 // expected-note@-1 {{Use of memory after it is freed}}
83 void deref_after_scope_wchar_t(bool cond) {
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}}
92 const wchar_t *c2 = s.c_str();
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}}
101 consume(d); // expected-warning {{Use of memory after it is freed}}
102 // expected-note@-1 {{Use of memory after it is freed}}
106 void deref_after_scope_char16_t_cstr() {
110 c16 = s16.c_str(); // expected-note {{Dangling inner pointer obtained here}}
111 } // expected-note {{Inner pointer invalidated by call to destructor}}
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}}
118 void deref_after_scope_char32_t_data() {
122 c32 = s32.data(); // expected-note {{Dangling inner pointer obtained here}}
123 } // expected-note {{Inner pointer invalidated by call to destructor}}
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}}
130 void multiple_symbols(bool cond) {
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}}
141 const char *c2 = s2.c_str();
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}}
150 consume(d1); // expected-warning {{Use of memory after it is freed}}
151 } // expected-note@-1 {{Use of memory after it is freed}}
154 void deref_after_equals() {
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}}
163 void deref_after_plus_equals() {
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}}
172 void deref_after_clear() {
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}}
181 void deref_after_append() {
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}}
190 void deref_after_assign() {
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}}
199 void deref_after_erase() {
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}}
208 void deref_after_insert() {
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}}
217 void deref_after_replace() {
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}}
226 void deref_after_pop_back() {
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}}
235 void deref_after_push_back() {
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}}
244 void deref_after_reserve() {
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}}
253 void deref_after_resize() {
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}}
262 void deref_after_shrink_to_fit() {
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}}
271 void deref_after_swap() {
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}}
280 void deref_after_scope_ok(bool cond) {
288 consume(c); // no-warning
290 consume(d); // no-warning