1b0914e72SArtem Dergachev // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=cplusplus.InnerPointer \
2c1dafd7bSGabor Horvath // RUN: -Wno-dangling -Wno-dangling-field -Wno-return-stack-address \
3391b19c7SKristof Umann // RUN: %s -analyzer-output=text -verify
488ad704bSReka Kovacs
5391b19c7SKristof Umann #include "Inputs/system-header-simulator-cxx.h"
688ad704bSReka Kovacs namespace std {
788ad704bSReka Kovacs
8c74cfc42SReka Kovacs template <typename T>
9c74cfc42SReka Kovacs void func_ref(T &a);
10c74cfc42SReka Kovacs
11c74cfc42SReka Kovacs template <typename T>
12c74cfc42SReka Kovacs void func_const_ref(const T &a);
13c74cfc42SReka Kovacs
14c74cfc42SReka Kovacs template <typename T>
15c74cfc42SReka Kovacs void func_value(T a);
16c74cfc42SReka Kovacs
17c74cfc42SReka Kovacs string my_string = "default";
18c74cfc42SReka Kovacs void default_arg(int a = 42, string &b = my_string);
19c74cfc42SReka Kovacs
20663ac91eSValeriy Savchenko template <class T>
21663ac91eSValeriy Savchenko T *addressof(T &arg);
22663ac91eSValeriy Savchenko
23*cf7cd664SAli Shuja Siddiqui template <class T>
24*cf7cd664SAli Shuja Siddiqui T *__addressof(T &arg);
25*cf7cd664SAli Shuja Siddiqui
26663ac91eSValeriy Savchenko char *data(std::string &c);
27663ac91eSValeriy Savchenko
2888ad704bSReka Kovacs } // end namespace std
2988ad704bSReka Kovacs
consume(const char *)3088ad704bSReka Kovacs void consume(const char *) {}
consume(const wchar_t *)3188ad704bSReka Kovacs void consume(const wchar_t *) {}
consume(const char16_t *)3288ad704bSReka Kovacs void consume(const char16_t *) {}
consume(const char32_t *)3388ad704bSReka Kovacs void consume(const char32_t *) {}
3488ad704bSReka Kovacs
35c74cfc42SReka Kovacs //=--------------------------------------=//
36c74cfc42SReka Kovacs // `std::string` member functions //
37c74cfc42SReka Kovacs //=--------------------------------------=//
38c74cfc42SReka Kovacs
deref_after_scope_char(bool cond)3988ad704bSReka Kovacs void deref_after_scope_char(bool cond) {
4088ad704bSReka Kovacs const char *c, *d;
4188ad704bSReka Kovacs {
4288ad704bSReka Kovacs std::string s;
43bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
44bb2749a5SReka Kovacs d = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
45bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
46bb2749a5SReka Kovacs // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
4788ad704bSReka Kovacs std::string s;
4888ad704bSReka Kovacs const char *c2 = s.c_str();
4988ad704bSReka Kovacs if (cond) {
502e896b8bSCsaba Dabis // expected-note@-1 {{Assuming 'cond' is true}}
5188ad704bSReka Kovacs // expected-note@-2 {{Taking true branch}}
522e896b8bSCsaba Dabis // expected-note@-3 {{Assuming 'cond' is false}}
5388ad704bSReka Kovacs // expected-note@-4 {{Taking false branch}}
54bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
55bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
5688ad704bSReka Kovacs } else {
57bb2749a5SReka Kovacs consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}
58bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
5988ad704bSReka Kovacs }
6088ad704bSReka Kovacs }
6188ad704bSReka Kovacs
deref_after_scope_char_data_non_const()6288ad704bSReka Kovacs void deref_after_scope_char_data_non_const() {
6388ad704bSReka Kovacs char *c;
6488ad704bSReka Kovacs {
6588ad704bSReka Kovacs std::string s;
66bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
67bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
6888ad704bSReka Kovacs std::string s;
6988ad704bSReka Kovacs char *c2 = s.data();
70bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
71bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
7288ad704bSReka Kovacs }
7388ad704bSReka Kovacs
deref_after_scope_wchar_t(bool cond)7488ad704bSReka Kovacs void deref_after_scope_wchar_t(bool cond) {
7588ad704bSReka Kovacs const wchar_t *c, *d;
7688ad704bSReka Kovacs {
7788ad704bSReka Kovacs std::wstring s;
78bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}
79bb2749a5SReka Kovacs d = s.data(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}
80bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::wstring' deallocated by call to destructor}}
81bb2749a5SReka Kovacs // expected-note@-1 {{Inner buffer of 'std::wstring' deallocated by call to destructor}}
8288ad704bSReka Kovacs std::wstring s;
8388ad704bSReka Kovacs const wchar_t *c2 = s.c_str();
8488ad704bSReka Kovacs if (cond) {
852e896b8bSCsaba Dabis // expected-note@-1 {{Assuming 'cond' is true}}
8688ad704bSReka Kovacs // expected-note@-2 {{Taking true branch}}
872e896b8bSCsaba Dabis // expected-note@-3 {{Assuming 'cond' is false}}
8888ad704bSReka Kovacs // expected-note@-4 {{Taking false branch}}
89bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
90bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
9188ad704bSReka Kovacs } else {
92bb2749a5SReka Kovacs consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}
93bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
9488ad704bSReka Kovacs }
9588ad704bSReka Kovacs }
9688ad704bSReka Kovacs
deref_after_scope_char16_t_cstr()9788ad704bSReka Kovacs void deref_after_scope_char16_t_cstr() {
9888ad704bSReka Kovacs const char16_t *c16;
9988ad704bSReka Kovacs {
10088ad704bSReka Kovacs std::u16string s16;
101bb2749a5SReka Kovacs c16 = s16.c_str(); // expected-note {{Pointer to inner buffer of 'std::u16string' obtained here}}
102bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::u16string' deallocated by call to destructor}}
10388ad704bSReka Kovacs std::u16string s16;
10488ad704bSReka Kovacs const char16_t *c16_2 = s16.c_str();
105bb2749a5SReka Kovacs consume(c16); // expected-warning {{Inner pointer of container used after re/deallocation}}
106bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
10788ad704bSReka Kovacs }
10888ad704bSReka Kovacs
deref_after_scope_char32_t_data()10988ad704bSReka Kovacs void deref_after_scope_char32_t_data() {
11088ad704bSReka Kovacs const char32_t *c32;
11188ad704bSReka Kovacs {
11288ad704bSReka Kovacs std::u32string s32;
113bb2749a5SReka Kovacs c32 = s32.data(); // expected-note {{Pointer to inner buffer of 'std::u32string' obtained here}}
114bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::u32string' deallocated by call to destructor}}
11588ad704bSReka Kovacs std::u32string s32;
11688ad704bSReka Kovacs const char32_t *c32_2 = s32.data();
117bb2749a5SReka Kovacs consume(c32); // expected-warning {{Inner pointer of container used after re/deallocation}}
118bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
11988ad704bSReka Kovacs }
12088ad704bSReka Kovacs
multiple_symbols(bool cond)12188ad704bSReka Kovacs void multiple_symbols(bool cond) {
12288ad704bSReka Kovacs const char *c1, *d1;
12388ad704bSReka Kovacs {
12488ad704bSReka Kovacs std::string s1;
125bb2749a5SReka Kovacs c1 = s1.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
126bb2749a5SReka Kovacs d1 = s1.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
12788ad704bSReka Kovacs const char *local = s1.c_str();
12888ad704bSReka Kovacs consume(local); // no-warning
129bb2749a5SReka Kovacs } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
130bb2749a5SReka Kovacs // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
13188ad704bSReka Kovacs std::string s2;
13288ad704bSReka Kovacs const char *c2 = s2.c_str();
13388ad704bSReka Kovacs if (cond) {
1342e896b8bSCsaba Dabis // expected-note@-1 {{Assuming 'cond' is true}}
13588ad704bSReka Kovacs // expected-note@-2 {{Taking true branch}}
1362e896b8bSCsaba Dabis // expected-note@-3 {{Assuming 'cond' is false}}
13788ad704bSReka Kovacs // expected-note@-4 {{Taking false branch}}
138bb2749a5SReka Kovacs consume(c1); // expected-warning {{Inner pointer of container used after re/deallocation}}
139bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
14088ad704bSReka Kovacs } else {
141bb2749a5SReka Kovacs consume(d1); // expected-warning {{Inner pointer of container used after re/deallocation}}
142bb2749a5SReka Kovacs } // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
14388ad704bSReka Kovacs }
14488ad704bSReka Kovacs
deref_after_scope_ok(bool cond)145c74cfc42SReka Kovacs void deref_after_scope_ok(bool cond) {
146c74cfc42SReka Kovacs const char *c, *d;
147c74cfc42SReka Kovacs std::string s;
148c74cfc42SReka Kovacs {
149c74cfc42SReka Kovacs c = s.c_str();
150c74cfc42SReka Kovacs d = s.data();
151c74cfc42SReka Kovacs }
152c74cfc42SReka Kovacs if (cond)
153c74cfc42SReka Kovacs consume(c); // no-warning
154c74cfc42SReka Kovacs else
155c74cfc42SReka Kovacs consume(d); // no-warning
156c74cfc42SReka Kovacs }
157c74cfc42SReka Kovacs
deref_after_equals()15888ad704bSReka Kovacs void deref_after_equals() {
15988ad704bSReka Kovacs const char *c;
16088ad704bSReka Kovacs std::string s = "hello";
161bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
162bb2749a5SReka Kovacs s = "world"; // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator='}}
163bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
164bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
16588ad704bSReka Kovacs }
16688ad704bSReka Kovacs
deref_after_plus_equals()16788ad704bSReka Kovacs void deref_after_plus_equals() {
16888ad704bSReka Kovacs const char *c;
16988ad704bSReka Kovacs std::string s = "hello";
170bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
171bb2749a5SReka Kovacs s += " world"; // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator+='}}
172bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
173bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
17488ad704bSReka Kovacs }
17588ad704bSReka Kovacs
deref_after_clear()17688ad704bSReka Kovacs void deref_after_clear() {
17788ad704bSReka Kovacs const char *c;
17888ad704bSReka Kovacs std::string s;
179bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
180bb2749a5SReka Kovacs s.clear(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}}
181bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
182bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
18388ad704bSReka Kovacs }
18488ad704bSReka Kovacs
deref_after_append()18588ad704bSReka Kovacs void deref_after_append() {
18688ad704bSReka Kovacs const char *c;
18788ad704bSReka Kovacs std::string s = "hello";
188bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
189bb2749a5SReka Kovacs s.append(2, 'x'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'append'}}
190bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
191bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
19288ad704bSReka Kovacs }
19388ad704bSReka Kovacs
deref_after_assign()19488ad704bSReka Kovacs void deref_after_assign() {
19588ad704bSReka Kovacs const char *c;
19688ad704bSReka Kovacs std::string s;
197bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
198bb2749a5SReka Kovacs s.assign(4, 'a'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'assign'}}
199bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
200bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
20188ad704bSReka Kovacs }
20288ad704bSReka Kovacs
deref_after_erase()20388ad704bSReka Kovacs void deref_after_erase() {
20488ad704bSReka Kovacs const char *c;
20588ad704bSReka Kovacs std::string s = "hello";
206bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
207bb2749a5SReka Kovacs s.erase(0, 2); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'erase'}}
208bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
209bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
21088ad704bSReka Kovacs }
21188ad704bSReka Kovacs
deref_after_insert()21288ad704bSReka Kovacs void deref_after_insert() {
21388ad704bSReka Kovacs const char *c;
21488ad704bSReka Kovacs std::string s = "ello";
215bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
216bb2749a5SReka Kovacs s.insert(0, 1, 'h'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'insert'}}
217bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
218bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
21988ad704bSReka Kovacs }
22088ad704bSReka Kovacs
deref_after_replace()22188ad704bSReka Kovacs void deref_after_replace() {
22288ad704bSReka Kovacs const char *c;
22388ad704bSReka Kovacs std::string s = "hello world";
224bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
225bb2749a5SReka Kovacs s.replace(6, 5, "string"); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'replace'}}
226bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
227bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
22888ad704bSReka Kovacs }
22988ad704bSReka Kovacs
deref_after_pop_back()23088ad704bSReka Kovacs void deref_after_pop_back() {
23188ad704bSReka Kovacs const char *c;
23288ad704bSReka Kovacs std::string s;
233bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
234bb2749a5SReka Kovacs s.pop_back(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'pop_back'}}
235bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
236bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
23788ad704bSReka Kovacs }
23888ad704bSReka Kovacs
deref_after_push_back()23988ad704bSReka Kovacs void deref_after_push_back() {
24088ad704bSReka Kovacs const char *c;
24188ad704bSReka Kovacs std::string s;
242bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
243bb2749a5SReka Kovacs s.push_back('c'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'push_back'}}
244bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
245bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
24688ad704bSReka Kovacs }
24788ad704bSReka Kovacs
deref_after_reserve()24888ad704bSReka Kovacs void deref_after_reserve() {
24988ad704bSReka Kovacs const char *c;
25088ad704bSReka Kovacs std::string s;
251bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
252bb2749a5SReka Kovacs s.reserve(5); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'reserve'}}
253bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
254bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
25588ad704bSReka Kovacs }
25688ad704bSReka Kovacs
deref_after_resize()25788ad704bSReka Kovacs void deref_after_resize() {
25888ad704bSReka Kovacs const char *c;
25988ad704bSReka Kovacs std::string s;
260bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
261bb2749a5SReka Kovacs s.resize(5); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'resize'}}
262bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
263bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
26488ad704bSReka Kovacs }
26588ad704bSReka Kovacs
deref_after_shrink_to_fit()26688ad704bSReka Kovacs void deref_after_shrink_to_fit() {
26788ad704bSReka Kovacs const char *c;
26888ad704bSReka Kovacs std::string s;
269bb2749a5SReka Kovacs c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
270bb2749a5SReka Kovacs s.shrink_to_fit(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'shrink_to_fit'}}
271bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
272bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
27388ad704bSReka Kovacs }
27488ad704bSReka Kovacs
deref_after_swap()27588ad704bSReka Kovacs void deref_after_swap() {
27688ad704bSReka Kovacs const char *c;
27788ad704bSReka Kovacs std::string s1, s2;
278bb2749a5SReka Kovacs c = s1.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
279bb2749a5SReka Kovacs s1.swap(s2); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'swap'}}
280bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
281bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
282bb2749a5SReka Kovacs }
283bb2749a5SReka Kovacs
deref_after_std_data()284663ac91eSValeriy Savchenko void deref_after_std_data() {
285663ac91eSValeriy Savchenko const char *c;
286663ac91eSValeriy Savchenko std::string s;
287663ac91eSValeriy Savchenko c = std::data(s); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
288663ac91eSValeriy Savchenko s.push_back('c'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'push_back'}}
289663ac91eSValeriy Savchenko consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
290663ac91eSValeriy Savchenko // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
291663ac91eSValeriy Savchenko }
292663ac91eSValeriy Savchenko
293bb2749a5SReka Kovacs struct S {
294bb2749a5SReka Kovacs std::string s;
nameS295bb2749a5SReka Kovacs const char *name() {
296bb2749a5SReka Kovacs return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
297bb2749a5SReka Kovacs // expected-note@-1 {{Pointer to inner buffer of 'std::string' obtained here}}
298bb2749a5SReka Kovacs }
clearS299bb2749a5SReka Kovacs void clear() {
300bb2749a5SReka Kovacs s.clear(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}}
301bb2749a5SReka Kovacs }
~SS302bb2749a5SReka Kovacs ~S() {} // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
303bb2749a5SReka Kovacs };
304bb2749a5SReka Kovacs
cleared_through_method()305bb2749a5SReka Kovacs void cleared_through_method() {
306bb2749a5SReka Kovacs S x;
307bb2749a5SReka Kovacs const char *c = x.name(); // expected-note {{Calling 'S::name'}}
308bb2749a5SReka Kovacs // expected-note@-1 {{Returning from 'S::name'}}
309bb2749a5SReka Kovacs x.clear(); // expected-note {{Calling 'S::clear'}}
310bb2749a5SReka Kovacs // expected-note@-1 {{Returning; inner buffer was reallocated}}
311bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
312bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
313bb2749a5SReka Kovacs }
314bb2749a5SReka Kovacs
destroyed_through_method()315bb2749a5SReka Kovacs void destroyed_through_method() {
316bb2749a5SReka Kovacs S y;
317bb2749a5SReka Kovacs const char *c = y.name(); // expected-note {{Calling 'S::name'}}
318bb2749a5SReka Kovacs // expected-note@-1 {{Returning from 'S::name'}}
319bb2749a5SReka Kovacs y.~S(); // expected-note {{Calling '~S'}}
320bb2749a5SReka Kovacs // expected-note@-1 {{Returning; inner buffer was deallocated}}
321bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
322bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
32388ad704bSReka Kovacs }
32488ad704bSReka Kovacs
325c74cfc42SReka Kovacs //=---------------------------=//
326c74cfc42SReka Kovacs // Other STL functions //
327c74cfc42SReka Kovacs //=---------------------------=//
328c74cfc42SReka Kovacs
STL_func_ref()329c74cfc42SReka Kovacs void STL_func_ref() {
330c74cfc42SReka Kovacs const char *c;
33188ad704bSReka Kovacs std::string s;
332bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
333bb2749a5SReka Kovacs std::func_ref(s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}}
334bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
335bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
33688ad704bSReka Kovacs }
337c74cfc42SReka Kovacs
STL_func_const_ref()338c74cfc42SReka Kovacs void STL_func_const_ref() {
339c74cfc42SReka Kovacs const char *c;
340c74cfc42SReka Kovacs std::string s;
341c74cfc42SReka Kovacs c = s.c_str();
342c74cfc42SReka Kovacs std::func_const_ref(s);
34388ad704bSReka Kovacs consume(c); // no-warning
344c74cfc42SReka Kovacs }
345c74cfc42SReka Kovacs
STL_func_value()346c74cfc42SReka Kovacs void STL_func_value() {
347c74cfc42SReka Kovacs const char *c;
348c74cfc42SReka Kovacs std::string s;
349c74cfc42SReka Kovacs c = s.c_str();
350c74cfc42SReka Kovacs std::func_value(s);
351c74cfc42SReka Kovacs consume(c); // no-warning
352c74cfc42SReka Kovacs }
353c74cfc42SReka Kovacs
func_ptr_known()354c74cfc42SReka Kovacs void func_ptr_known() {
355c74cfc42SReka Kovacs const char *c;
356c74cfc42SReka Kovacs std::string s;
357c74cfc42SReka Kovacs void (*func_ptr)(std::string &) = std::func_ref<std::string>;
358bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
359bb2749a5SReka Kovacs func_ptr(s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}}
360bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
361bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
362c74cfc42SReka Kovacs }
363c74cfc42SReka Kovacs
func_ptr_unknown(void (* func_ptr)(std::string &))364c74cfc42SReka Kovacs void func_ptr_unknown(void (*func_ptr)(std::string &)) {
365c74cfc42SReka Kovacs const char *c;
366c74cfc42SReka Kovacs std::string s;
367c74cfc42SReka Kovacs c = s.c_str();
368c74cfc42SReka Kovacs func_ptr(s);
369c74cfc42SReka Kovacs consume(c); // no-warning
370c74cfc42SReka Kovacs }
371c74cfc42SReka Kovacs
func_default_arg()372c74cfc42SReka Kovacs void func_default_arg() {
373c74cfc42SReka Kovacs const char *c;
374c74cfc42SReka Kovacs std::string s;
375bb2749a5SReka Kovacs c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
376bb2749a5SReka Kovacs default_arg(3, s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'default_arg'}}
377bb2749a5SReka Kovacs consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
378bb2749a5SReka Kovacs // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
37988ad704bSReka Kovacs }
380122171e2SReka Kovacs
func_addressof()381663ac91eSValeriy Savchenko void func_addressof() {
382663ac91eSValeriy Savchenko const char *c;
383663ac91eSValeriy Savchenko std::string s;
384663ac91eSValeriy Savchenko c = s.c_str();
38572315d02SRichard Smith (void)addressof(s);
386663ac91eSValeriy Savchenko consume(c); // no-warning
387663ac91eSValeriy Savchenko }
388663ac91eSValeriy Savchenko
func_AddressofFn_()389*cf7cd664SAli Shuja Siddiqui void func_AddressofFn_() {
390*cf7cd664SAli Shuja Siddiqui const char *c;
391*cf7cd664SAli Shuja Siddiqui std::string s;
392*cf7cd664SAli Shuja Siddiqui c = s.c_str();
393*cf7cd664SAli Shuja Siddiqui (void)std::__addressof(s);
394*cf7cd664SAli Shuja Siddiqui consume(c); // no-warning
395*cf7cd664SAli Shuja Siddiqui }
396*cf7cd664SAli Shuja Siddiqui
func_std_data()397663ac91eSValeriy Savchenko void func_std_data() {
398663ac91eSValeriy Savchenko const char *c;
399663ac91eSValeriy Savchenko std::string s;
400663ac91eSValeriy Savchenko c = std::data(s);
401663ac91eSValeriy Savchenko consume(c); // no-warning
402663ac91eSValeriy Savchenko }
403663ac91eSValeriy Savchenko
404bb2749a5SReka Kovacs struct T {
to_stringT405122171e2SReka Kovacs std::string to_string() { return s; }
406663ac91eSValeriy Savchenko
407122171e2SReka Kovacs private:
408122171e2SReka Kovacs std::string s;
409122171e2SReka Kovacs };
410122171e2SReka Kovacs
escape_via_return_temp()411122171e2SReka Kovacs const char *escape_via_return_temp() {
412bb2749a5SReka Kovacs T x;
413bb2749a5SReka Kovacs return x.to_string().c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
414bb2749a5SReka Kovacs // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
415bb2749a5SReka Kovacs // expected-warning@-2 {{Inner pointer of container used after re/deallocation}}
416bb2749a5SReka Kovacs // expected-note@-3 {{Inner pointer of container used after re/deallocation}}
417122171e2SReka Kovacs }
418122171e2SReka Kovacs
escape_via_return_local()419122171e2SReka Kovacs const char *escape_via_return_local() {
420122171e2SReka Kovacs std::string s;
421bb2749a5SReka Kovacs return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
422bb2749a5SReka Kovacs // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
42333e5a158SGeorge Karpenkov // expected-warning@-2 {{Inner pointer of container used after re/deallocation}}
42433e5a158SGeorge Karpenkov // expected-note@-3 {{Inner pointer of container used after re/deallocation}}
42533e5a158SGeorge Karpenkov }
426bfd9cfdeSReka Kovacs
427bfd9cfdeSReka Kovacs
428bfd9cfdeSReka Kovacs char *c();
429bfd9cfdeSReka Kovacs class A {};
430bfd9cfdeSReka Kovacs
no_CXXRecordDecl()431bfd9cfdeSReka Kovacs void no_CXXRecordDecl() {
432bfd9cfdeSReka Kovacs A a, *b;
433bfd9cfdeSReka Kovacs *(void **)&b = c() + 1;
434bfd9cfdeSReka Kovacs *b = a; // no-crash
435bfd9cfdeSReka Kovacs }
43673b38668SArtem Dergachev
checkReference(std::string & s)43773b38668SArtem Dergachev void checkReference(std::string &s) {
43873b38668SArtem Dergachev const char *c = s.c_str();
43973b38668SArtem Dergachev }
440