brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.2 KiB · 4cb1944 Raw
440 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=cplusplus.InnerPointer \2// RUN:   -Wno-dangling -Wno-dangling-field -Wno-return-stack-address \3// RUN:   %s -analyzer-output=text -verify4 5#include "Inputs/system-header-simulator-cxx.h"6namespace std {7 8template <typename T>9void func_ref(T &a);10 11template <typename T>12void func_const_ref(const T &a);13 14template <typename T>15void func_value(T a);16 17string my_string = "default";18void default_arg(int a = 42, string &b = my_string);19 20template <class T>21T *addressof(T &arg);22 23template <class T>24T *__addressof(T &arg);25 26char *data(std::string &c);27 28} // end namespace std29 30void consume(const char *) {}31void consume(const wchar_t *) {}32void consume(const char16_t *) {}33void consume(const char32_t *) {}34 35//=--------------------------------------=//36//     `std::string` member functions     //37//=--------------------------------------=//38 39void deref_after_scope_char(bool cond) {40  const char *c, *d;41  {42    std::string s;43    c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}44    d = s.data();  // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}45  }                // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}46  // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}47  std::string s;48  const char *c2 = s.c_str();49  if (cond) {50    // expected-note@-1 {{Assuming 'cond' is true}}51    // expected-note@-2 {{Taking true branch}}52    // expected-note@-3 {{Assuming 'cond' is false}}53    // expected-note@-4 {{Taking false branch}}54    consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}55    // expected-note@-1 {{Inner pointer of container used after re/deallocation}}56  } else {57    consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}58    // expected-note@-1 {{Inner pointer of container used after re/deallocation}}59  }60}61 62void deref_after_scope_char_data_non_const() {63  char *c;64  {65    std::string s;66    c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}67  }               // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}68  std::string s;69  char *c2 = s.data();70  consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}71  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}72}73 74void deref_after_scope_wchar_t(bool cond) {75  const wchar_t *c, *d;76  {77    std::wstring s;78    c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}79    d = s.data();  // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}80  }                // expected-note {{Inner buffer of 'std::wstring' deallocated by call to destructor}}81  // expected-note@-1 {{Inner buffer of 'std::wstring' deallocated by call to destructor}}82  std::wstring s;83  const wchar_t *c2 = s.c_str();84  if (cond) {85    // expected-note@-1 {{Assuming 'cond' is true}}86    // expected-note@-2 {{Taking true branch}}87    // expected-note@-3 {{Assuming 'cond' is false}}88    // expected-note@-4 {{Taking false branch}}89    consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}90    // expected-note@-1 {{Inner pointer of container used after re/deallocation}}91  } else {92    consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}93    // expected-note@-1 {{Inner pointer of container used after re/deallocation}}94  }95}96 97void deref_after_scope_char16_t_cstr() {98  const char16_t *c16;99  {100    std::u16string s16;101    c16 = s16.c_str(); // expected-note {{Pointer to inner buffer of 'std::u16string' obtained here}}102  }                    // expected-note {{Inner buffer of 'std::u16string' deallocated by call to destructor}}103  std::u16string s16;104  const char16_t *c16_2 = s16.c_str();105  consume(c16); // expected-warning {{Inner pointer of container used after re/deallocation}}106  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}107}108 109void deref_after_scope_char32_t_data() {110  const char32_t *c32;111  {112    std::u32string s32;113    c32 = s32.data(); // expected-note {{Pointer to inner buffer of 'std::u32string' obtained here}}114  }                   // expected-note {{Inner buffer of 'std::u32string' deallocated by call to destructor}}115  std::u32string s32;116  const char32_t *c32_2 = s32.data();117  consume(c32); // expected-warning {{Inner pointer of container used after re/deallocation}}118  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}119}120 121void multiple_symbols(bool cond) {122  const char *c1, *d1;123  {124    std::string s1;125    c1 = s1.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}126    d1 = s1.data();  // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}127    const char *local = s1.c_str();128    consume(local); // no-warning129  }                 // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}130  // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}131  std::string s2;132  const char *c2 = s2.c_str();133  if (cond) {134    // expected-note@-1 {{Assuming 'cond' is true}}135    // expected-note@-2 {{Taking true branch}}136    // expected-note@-3 {{Assuming 'cond' is false}}137    // expected-note@-4 {{Taking false branch}}138    consume(c1); // expected-warning {{Inner pointer of container used after re/deallocation}}139    // expected-note@-1 {{Inner pointer of container used after re/deallocation}}140  } else {141    consume(d1); // expected-warning {{Inner pointer of container used after re/deallocation}}142  }              // expected-note@-1 {{Inner pointer of container used after re/deallocation}}143}144 145void deref_after_scope_ok(bool cond) {146  const char *c, *d;147  std::string s;148  {149    c = s.c_str();150    d = s.data();151  }152  if (cond)153    consume(c); // no-warning154  else155    consume(d); // no-warning156}157 158void deref_after_equals() {159  const char *c;160  std::string s = "hello";161  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}162  s = "world";   // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator='}}163  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}164  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}165}166 167void deref_after_plus_equals() {168  const char *c;169  std::string s = "hello";170  c = s.data();  // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}171  s += " world"; // expected-note {{Inner buffer of 'std::string' reallocated by call to 'operator+='}}172  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}173  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}174}175 176void deref_after_clear() {177  const char *c;178  std::string s;179  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}180  s.clear();     // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}}181  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}182  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}183}184 185void deref_after_append() {186  const char *c;187  std::string s = "hello";188  c = s.c_str();    // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}189  s.append(2, 'x'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'append'}}190  consume(c);       // expected-warning {{Inner pointer of container used after re/deallocation}}191  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}192}193 194void deref_after_assign() {195  const char *c;196  std::string s;197  c = s.data();     // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}198  s.assign(4, 'a'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'assign'}}199  consume(c);       // expected-warning {{Inner pointer of container used after re/deallocation}}200  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}201}202 203void deref_after_erase() {204  const char *c;205  std::string s = "hello";206  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}207  s.erase(0, 2); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'erase'}}208  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}209  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}210}211 212void deref_after_insert() {213  const char *c;214  std::string s = "ello";215  c = s.c_str();       // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}216  s.insert(0, 1, 'h'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'insert'}}217  consume(c);          // expected-warning {{Inner pointer of container used after re/deallocation}}218  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}219}220 221void deref_after_replace() {222  const char *c;223  std::string s = "hello world";224  c = s.c_str();             // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}225  s.replace(6, 5, "string"); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'replace'}}226  consume(c);                // expected-warning {{Inner pointer of container used after re/deallocation}}227  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}228}229 230void deref_after_pop_back() {231  const char *c;232  std::string s;233  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}234  s.pop_back();  // expected-note {{Inner buffer of 'std::string' reallocated by call to 'pop_back'}}235  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}236  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}237}238 239void deref_after_push_back() {240  const char *c;241  std::string s;242  c = s.data();     // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}243  s.push_back('c'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'push_back'}}244  consume(c);       // expected-warning {{Inner pointer of container used after re/deallocation}}245  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}246}247 248void deref_after_reserve() {249  const char *c;250  std::string s;251  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}252  s.reserve(5);  // expected-note {{Inner buffer of 'std::string' reallocated by call to 'reserve'}}253  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}254  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}255}256 257void deref_after_resize() {258  const char *c;259  std::string s;260  c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}261  s.resize(5);  // expected-note {{Inner buffer of 'std::string' reallocated by call to 'resize'}}262  consume(c);   // expected-warning {{Inner pointer of container used after re/deallocation}}263  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}264}265 266void deref_after_shrink_to_fit() {267  const char *c;268  std::string s;269  c = s.data();      // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}270  s.shrink_to_fit(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'shrink_to_fit'}}271  consume(c);        // expected-warning {{Inner pointer of container used after re/deallocation}}272  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}273}274 275void deref_after_swap() {276  const char *c;277  std::string s1, s2;278  c = s1.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}279  s1.swap(s2);   // expected-note {{Inner buffer of 'std::string' reallocated by call to 'swap'}}280  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}281  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}282}283 284void deref_after_std_data() {285  const char *c;286  std::string s;287  c = std::data(s); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}288  s.push_back('c'); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'push_back'}}289  consume(c);       // expected-warning {{Inner pointer of container used after re/deallocation}}290  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}291}292 293struct S {294  std::string s;295  const char *name() {296    return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}297                      // expected-note@-1 {{Pointer to inner buffer of 'std::string' obtained here}}298  }299  void clear() {300    s.clear(); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'clear'}}301  }302  ~S() {} // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}303};304 305void cleared_through_method() {306  S x;307  const char *c = x.name(); // expected-note {{Calling 'S::name'}}308                            // expected-note@-1 {{Returning from 'S::name'}}309  x.clear(); // expected-note {{Calling 'S::clear'}}310             // expected-note@-1 {{Returning; inner buffer was reallocated}}311  consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}312  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}313}314 315void destroyed_through_method() {316  S y;317  const char *c = y.name(); // expected-note {{Calling 'S::name'}}318                            // expected-note@-1 {{Returning from 'S::name'}}319  y.~S(); // expected-note {{Calling '~S'}}320          // expected-note@-1 {{Returning; inner buffer was deallocated}}321  consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}322  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}323}324 325//=---------------------------=//326//     Other STL functions     //327//=---------------------------=//328 329void STL_func_ref() {330  const char *c;331  std::string s;332  c = s.c_str();    // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}333  std::func_ref(s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}}334  consume(c);       // expected-warning {{Inner pointer of container used after re/deallocation}}335  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}336}337 338void STL_func_const_ref() {339  const char *c;340  std::string s;341  c = s.c_str();342  std::func_const_ref(s);343  consume(c); // no-warning344}345 346void STL_func_value() {347  const char *c;348  std::string s;349  c = s.c_str();350  std::func_value(s);351  consume(c); // no-warning352}353 354void func_ptr_known() {355  const char *c;356  std::string s;357  void (*func_ptr)(std::string &) = std::func_ref<std::string>;358  c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}359  func_ptr(s);   // expected-note {{Inner buffer of 'std::string' reallocated by call to 'func_ref'}}360  consume(c);    // expected-warning {{Inner pointer of container used after re/deallocation}}361  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}362}363 364void func_ptr_unknown(void (*func_ptr)(std::string &)) {365  const char *c;366  std::string s;367  c = s.c_str();368  func_ptr(s);369  consume(c); // no-warning370}371 372void func_default_arg() {373  const char *c;374  std::string s;375  c = s.c_str();     // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}376  default_arg(3, s); // expected-note {{Inner buffer of 'std::string' reallocated by call to 'default_arg'}}377  consume(c);        // expected-warning {{Inner pointer of container used after re/deallocation}}378  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}379}380 381void func_addressof() {382  const char *c;383  std::string s;384  c = s.c_str();385  (void)addressof(s);386  consume(c); // no-warning387}388 389void func_AddressofFn_() {390  const char *c;391  std::string s;392  c = s.c_str();393  (void)std::__addressof(s);394  consume(c); // no-warning395}396 397void func_std_data() {398  const char *c;399  std::string s;400  c = std::data(s);401  consume(c); // no-warning402}403 404struct T {405  std::string to_string() { return s; }406 407private:408  std::string s;409};410 411const char *escape_via_return_temp() {412  T x;413  return x.to_string().c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}414  // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}415  // expected-warning@-2 {{Inner pointer of container used after re/deallocation}}416  // expected-note@-3 {{Inner pointer of container used after re/deallocation}}417}418 419const char *escape_via_return_local() {420  std::string s;421  return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}422                    // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}423                    // expected-warning@-2 {{Inner pointer of container used after re/deallocation}}424                    // expected-note@-3 {{Inner pointer of container used after re/deallocation}}425}426 427 428char *c();429class A {};430 431void no_CXXRecordDecl() {432  A a, *b;433  *(void **)&b = c() + 1;434  *b = a; // no-crash435}436 437void checkReference(std::string &s) {438  const char *c = s.c_str();439}440