brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · d5c75c4 Raw
122 lines · cpp
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=false7 8extern "C" char *strdup(const char* s);9extern "C" void free(void* ptr);10 11namespace std {12template<class T> struct remove_reference      { typedef T type; };13template<class T> struct remove_reference<T&>  { typedef T type; };14template<class T> struct remove_reference<T&&> { typedef T type; };15template<class T> typename remove_reference<T>::type&& move(T&& t);16}17 18void clang_analyzer_eval(int);19 20class StringUsed {21public: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;28private:29  char *str;30};31 32StringUsed::~StringUsed() {33  free(str);34}35 36StringUsed &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 released}}46                         // expected-note@-1{{Use of memory after it is released}}47                         // expected-note@-2{{Memory is allocated}}48  return *this;49}50 51StringUsed &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;62}63 64StringUsed::operator const char*() const {65  return str;66}67 68class StringUnused {69public: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;76private:77  char *str;78};79 80StringUnused::~StringUnused() {81  free(str);82}83 84StringUnused &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 released}}94                         // expected-note@-1{{Use of memory after it is released}}95  return *this;96}97 98StringUnused &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 here107  return *this;108}109 110StringUnused::operator const char*() const {111  return str;112}113 114 115int 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;121}122