summaryrefslogtreecommitdiff
path: root/test/Analysis/inner-pointer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/inner-pointer.cpp')
-rw-r--r--test/Analysis/inner-pointer.cpp94
1 files changed, 83 insertions, 11 deletions
diff --git a/test/Analysis/inner-pointer.cpp b/test/Analysis/inner-pointer.cpp
index db9bf43109b2..230e3396c59e 100644
--- a/test/Analysis/inner-pointer.cpp
+++ b/test/Analysis/inner-pointer.cpp
@@ -1,4 +1,4 @@
-//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s -analyzer-output=text -verify
+//RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer %s -analyzer-output=text -verify
namespace std {
@@ -38,6 +38,18 @@ typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
+template <typename T>
+void func_ref(T &a);
+
+template <typename T>
+void func_const_ref(const T &a);
+
+template <typename T>
+void func_value(T a);
+
+string my_string = "default";
+void default_arg(int a = 42, string &b = my_string);
+
} // end namespace std
void consume(const char *) {}
@@ -45,6 +57,10 @@ void consume(const wchar_t *) {}
void consume(const char16_t *) {}
void consume(const char32_t *) {}
+//=--------------------------------------=//
+// `std::string` member functions //
+//=--------------------------------------=//
+
void deref_after_scope_char(bool cond) {
const char *c, *d;
{
@@ -151,6 +167,19 @@ void multiple_symbols(bool cond) {
} // expected-note@-1 {{Use of memory after it is freed}}
}
+void deref_after_scope_ok(bool cond) {
+ const char *c, *d;
+ std::string s;
+ {
+ c = s.c_str();
+ d = s.data();
+ }
+ if (cond)
+ consume(c); // no-warning
+ else
+ consume(d); // no-warning
+}
+
void deref_after_equals() {
const char *c;
std::string s = "hello";
@@ -277,15 +306,58 @@ void deref_after_swap() {
// expected-note@-1 {{Use of memory after it is freed}}
}
-void deref_after_scope_ok(bool cond) {
- const char *c, *d;
+//=---------------------------=//
+// Other STL functions //
+//=---------------------------=//
+
+void STL_func_ref() {
+ const char *c;
std::string s;
- {
- c = s.c_str();
- d = s.data();
- }
- if (cond)
- consume(c); // no-warning
- else
- consume(d); // no-warning
+ 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}}
+}
+
+void STL_func_const_ref() {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ std::func_const_ref(s);
+ consume(c); // no-warning
+}
+
+void STL_func_value() {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ std::func_value(s);
+ consume(c); // no-warning
+}
+
+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}}
+}
+
+void func_ptr_unknown(void (*func_ptr)(std::string &)) {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ func_ptr(s);
+ consume(c); // no-warning
+}
+
+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}}
}