diff options
Diffstat (limited to 'clang/test/Analysis/inner-pointer.cpp')
-rw-r--r-- | clang/test/Analysis/inner-pointer.cpp | 260 |
1 files changed, 146 insertions, 114 deletions
diff --git a/clang/test/Analysis/inner-pointer.cpp b/clang/test/Analysis/inner-pointer.cpp index fb8cc8ec33e..950270b2962 100644 --- a/clang/test/Analysis/inner-pointer.cpp +++ b/clang/test/Analysis/inner-pointer.cpp @@ -65,10 +65,10 @@ void deref_after_scope_char(bool cond) { const char *c, *d; { std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + d = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}} + // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}} std::string s; const char *c2 = s.c_str(); if (cond) { @@ -76,11 +76,11 @@ void deref_after_scope_char(bool cond) { // expected-note@-2 {{Taking true branch}} // expected-note@-3 {{Assuming 'cond' is 0}} // expected-note@-4 {{Taking false branch}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } else { - consume(d); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } } @@ -88,22 +88,22 @@ void deref_after_scope_char_data_non_const() { char *c; { std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}} std::string s; char *c2 = s.data(); - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_scope_wchar_t(bool cond) { const wchar_t *c, *d; { std::wstring s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}} + d = s.data(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}} + } // expected-note {{Inner buffer of 'std::wstring' deallocated by call to destructor}} + // expected-note@-1 {{Inner buffer of 'std::wstring' deallocated by call to destructor}} std::wstring s; const wchar_t *c2 = s.c_str(); if (cond) { @@ -111,11 +111,11 @@ void deref_after_scope_wchar_t(bool cond) { // expected-note@-2 {{Taking true branch}} // expected-note@-3 {{Assuming 'cond' is 0}} // expected-note@-4 {{Taking false branch}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } else { - consume(d); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } } @@ -123,36 +123,36 @@ void deref_after_scope_char16_t_cstr() { const char16_t *c16; { std::u16string s16; - c16 = s16.c_str(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} + c16 = s16.c_str(); // expected-note {{Pointer to inner buffer of 'std::u16string' obtained here}} + } // expected-note {{Inner buffer of 'std::u16string' deallocated by call to destructor}} std::u16string s16; const char16_t *c16_2 = s16.c_str(); - consume(c16); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c16); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_scope_char32_t_data() { const char32_t *c32; { std::u32string s32; - c32 = s32.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} + c32 = s32.data(); // expected-note {{Pointer to inner buffer of 'std::u32string' obtained here}} + } // expected-note {{Inner buffer of 'std::u32string' deallocated by call to destructor}} std::u32string s32; const char32_t *c32_2 = s32.data(); - consume(c32); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c32); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void multiple_symbols(bool cond) { const char *c1, *d1; { std::string s1; - c1 = s1.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d1 = s1.data(); // expected-note {{Dangling inner pointer obtained here}} + c1 = s1.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + d1 = s1.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} const char *local = s1.c_str(); consume(local); // no-warning - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} + } // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}} + // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}} std::string s2; const char *c2 = s2.c_str(); if (cond) { @@ -160,11 +160,11 @@ void multiple_symbols(bool cond) { // expected-note@-2 {{Taking true branch}} // expected-note@-3 {{Assuming 'cond' is 0}} // expected-note@-4 {{Taking false branch}} - consume(c1); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + consume(c1); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } else { - consume(d1); // expected-warning {{Use of memory after it is freed}} - } // expected-note@-1 {{Use of memory after it is freed}} + consume(d1); // expected-warning {{Inner pointer of container used after re/deallocation}} + } // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_scope_ok(bool cond) { @@ -183,127 +183,159 @@ void deref_after_scope_ok(bool cond) { void deref_after_equals() { const char *c; std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s = "world"; // expected-note {{Inner pointer invalidated by call to 'operator='}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s = "world"; // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator='}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_plus_equals() { const char *c; std::string s = "hello"; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s += " world"; // expected-note {{Inner pointer invalidated by call to 'operator+='}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s += " world"; // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator+='}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_clear() { const char *c; std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.clear(); // expected-note {{Inner pointer invalidated by call to 'clear'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.clear(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_append() { const char *c; std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.append(2, 'x'); // expected-note {{Inner pointer invalidated by call to 'append'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.append(2, 'x'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'append'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_assign() { const char *c; std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.assign(4, 'a'); // expected-note {{Inner pointer invalidated by call to 'assign'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.assign(4, 'a'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'assign'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_erase() { const char *c; std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.erase(0, 2); // expected-note {{Inner pointer invalidated by call to 'erase'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.erase(0, 2); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'erase'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_insert() { const char *c; std::string s = "ello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.insert(0, 1, 'h'); // expected-note {{Inner pointer invalidated by call to 'insert'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.insert(0, 1, 'h'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'insert'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_replace() { const char *c; std::string s = "hello world"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.replace(6, 5, "string"); // expected-note {{Inner pointer invalidated by call to 'replace'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.replace(6, 5, "string"); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'replace'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_pop_back() { const char *c; std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.pop_back(); // expected-note {{Inner pointer invalidated by call to 'pop_back'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.pop_back(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'pop_back'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_push_back() { const char *c; std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.push_back('c'); // expected-note {{Inner pointer invalidated by call to 'push_back'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.push_back('c'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'push_back'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_reserve() { const char *c; std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.reserve(5); // expected-note {{Inner pointer invalidated by call to 'reserve'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.reserve(5); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'reserve'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_resize() { const char *c; std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.resize(5); // expected-note {{Inner pointer invalidated by call to 'resize'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.resize(5); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'resize'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_shrink_to_fit() { const char *c; std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.shrink_to_fit(); // expected-note {{Inner pointer invalidated by call to 'shrink_to_fit'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s.shrink_to_fit(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'shrink_to_fit'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void deref_after_swap() { const char *c; std::string s1, s2; - c = s1.data(); // expected-note {{Dangling inner pointer obtained here}} - s1.swap(s2); // expected-note {{Inner pointer invalidated by call to 'swap'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s1.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + s1.swap(s2); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'swap'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} +} + +struct S { + std::string s; + const char *name() { + return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + // expected-note@-1 {{Pointer to inner buffer of 'std::string' obtained here}} + } + void clear() { + s.clear(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}} + } + ~S() {} // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}} +}; + +void cleared_through_method() { + S x; + const char *c = x.name(); // expected-note {{Calling 'S::name'}} + // expected-note@-1 {{Returning from 'S::name'}} + x.clear(); // expected-note {{Calling 'S::clear'}} + // expected-note@-1 {{Returning; inner buffer was reallocated}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} +} + +void destroyed_through_method() { + S y; + const char *c = y.name(); // expected-note {{Calling 'S::name'}} + // expected-note@-1 {{Returning from 'S::name'}} + y.~S(); // expected-note {{Calling '~S'}} + // expected-note@-1 {{Returning; inner buffer was deallocated}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } //=---------------------------=// @@ -313,10 +345,10 @@ void deref_after_swap() { void STL_func_ref() { const char *c; std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - std::func_ref(s); // expected-note {{Inner pointer invalidated by call to 'func_ref'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + std::func_ref(s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void STL_func_const_ref() { @@ -339,10 +371,10 @@ void func_ptr_known() { const char *c; std::string s; void (*func_ptr)(std::string &) = std::func_ref<std::string>; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - func_ptr(s); // expected-note {{Inner pointer invalidated by call to 'func_ref'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + func_ptr(s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } void func_ptr_unknown(void (*func_ptr)(std::string &)) { @@ -356,32 +388,32 @@ void func_ptr_unknown(void (*func_ptr)(std::string &)) { void func_default_arg() { const char *c; std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - default_arg(3, s); // expected-note {{Inner pointer invalidated by call to 'default_arg'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} + c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + default_arg(3, s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'default_arg'}} + consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}} + // expected-note@-1 {{Inner pointer of container used after re/deallocation}} } -struct S { +struct T { std::string to_string() { return s; } private: std::string s; }; const char *escape_via_return_temp() { - S x; - return x.to_string().c_str(); // expected-note {{Dangling inner pointer obtained here}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} - // expected-warning@-2 {{Use of memory after it is freed}} - // expected-note@-3 {{Use of memory after it is freed}} + T x; + return x.to_string().c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}} + // expected-warning@-2 {{Inner pointer of container used after re/deallocation}} + // expected-note@-3 {{Inner pointer of container used after re/deallocation}} } const char *escape_via_return_local() { std::string s; - return s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} -} // expected-warning {{Use of memory after it is freed}} -// expected-note@-1 {{Use of memory after it is freed}} + return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}} + // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}} +} // expected-warning {{Inner pointer of container used after re/deallocation}} +// expected-note@-1 {{Inner pointer of container used after re/deallocation}} char *c(); |