[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / Analysis / self-assign.cpp
blob7d3ea99b005de47cf70872c025912394584f531f
1 // RUN: %clang_analyze_cc1 -std=c++11 %s -verify -analyzer-output=text \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=cplusplus \
4 // RUN: -analyzer-checker=unix.Malloc \
5 // RUN: -analyzer-checker=debug.ExprInspection \
6 // RUN: -analyzer-config eagerly-assume=false
8 extern "C" char *strdup(const char* s);
9 extern "C" void free(void* ptr);
11 namespace std {
12 template<class T> struct remove_reference { typedef T type; };
13 template<class T> struct remove_reference<T&> { typedef T type; };
14 template<class T> struct remove_reference<T&&> { typedef T type; };
15 template<class T> typename remove_reference<T>::type&& move(T&& t);
18 void clang_analyzer_eval(int);
20 class StringUsed {
21 public:
22 StringUsed(const char *s = "") : str(strdup(s)) {}
23 StringUsed(const StringUsed &rhs) : str(strdup(rhs.str)) {}
24 ~StringUsed();
25 StringUsed& operator=(const StringUsed &rhs);
26 StringUsed& operator=(StringUsed &&rhs);
27 operator const char*() const;
28 private:
29 char *str;
32 StringUsed::~StringUsed() {
33 free(str);
36 StringUsed &StringUsed::operator=(const StringUsed &rhs) {
37 // expected-note@-1{{Assuming rhs == *this}}
38 // expected-note@-2{{Assuming rhs == *this}}
39 // expected-note@-3{{Assuming rhs != *this}}
40 clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}
41 // expected-warning@-1{{UNKNOWN}}
42 // expected-note@-2{{TRUE}}
43 // expected-note@-3{{UNKNOWN}}
44 free(str); // expected-note{{Memory is released}}
45 str = strdup(rhs.str); // expected-warning{{Use of memory after it is freed}}
46 // expected-note@-1{{Use of memory after it is freed}}
47 // expected-note@-2{{Memory is allocated}}
48 return *this;
51 StringUsed &StringUsed::operator=(StringUsed &&rhs) {
52 // expected-note@-1{{Assuming rhs == *this}}
53 // expected-note@-2{{Assuming rhs != *this}}
54 clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}
55 // expected-warning@-1{{UNKNOWN}}
56 // expected-note@-2{{TRUE}}
57 // expected-note@-3{{UNKNOWN}}
58 str = rhs.str;
59 rhs.str = nullptr; // expected-warning{{Potential memory leak}}
60 // expected-note@-1{{Potential memory leak}}
61 return *this;
64 StringUsed::operator const char*() const {
65 return str;
68 class StringUnused {
69 public:
70 StringUnused(const char *s = "") : str(strdup(s)) {}
71 StringUnused(const StringUnused &rhs) : str(strdup(rhs.str)) {}
72 ~StringUnused();
73 StringUnused& operator=(const StringUnused &rhs);
74 StringUnused& operator=(StringUnused &&rhs);
75 operator const char*() const;
76 private:
77 char *str;
80 StringUnused::~StringUnused() {
81 free(str);
84 StringUnused &StringUnused::operator=(const StringUnused &rhs) {
85 // expected-note@-1{{Assuming rhs == *this}}
86 // expected-note@-2{{Assuming rhs == *this}}
87 // expected-note@-3{{Assuming rhs != *this}}
88 clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}
89 // expected-warning@-1{{UNKNOWN}}
90 // expected-note@-2{{TRUE}}
91 // expected-note@-3{{UNKNOWN}}
92 free(str); // expected-note{{Memory is released}}
93 str = strdup(rhs.str); // expected-warning{{Use of memory after it is freed}}
94 // expected-note@-1{{Use of memory after it is freed}}
95 return *this;
98 StringUnused &StringUnused::operator=(StringUnused &&rhs) {
99 // expected-note@-1{{Assuming rhs == *this}}
100 // expected-note@-2{{Assuming rhs != *this}}
101 clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}
102 // expected-warning@-1{{UNKNOWN}}
103 // expected-note@-2{{TRUE}}
104 // expected-note@-3{{UNKNOWN}}
105 str = rhs.str;
106 rhs.str = nullptr; // FIXME: An improved leak checker should warn here
107 return *this;
110 StringUnused::operator const char*() const {
111 return str;
115 int main() {
116 StringUsed s1 ("test"), s2;
117 s2 = s1; // expected-note{{Calling copy assignment operator for 'StringUsed'}}
118 // expected-note@-1{{Returned allocated memory}}
119 s2 = std::move(s1); // expected-note{{Calling move assignment operator for 'StringUsed'}}
120 return 0;