brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 84a34af Raw
380 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++11 %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++17 %s3 4using size_t =  __typeof(sizeof(int));5 6void clang_analyzer_eval(bool);7void clang_analyzer_checkInlined(bool);8void clang_analyzer_warnIfReached();9void clang_analyzer_explain(int);10 11int a, b, c, d;12 13struct InlineDtor {14  static int cnt;15  static int dtorCalled;16  ~InlineDtor() {17    switch (dtorCalled % 4) {18    case 0:19      a = cnt++;20      break;21    case 1:22      b = cnt++;23      break;24    case 2:25      c = cnt++;26      break;27    case 3:28      d = cnt++;29      break;30    }31 32    ++dtorCalled;33  }34};35 36int InlineDtor::cnt = 0;37int InlineDtor::dtorCalled = 0;38 39void foo() {40  InlineDtor::cnt = 0;41  InlineDtor::dtorCalled = 0;42  InlineDtor arr[4];43}44 45void testAutoDtor() {46  foo();47 48  clang_analyzer_eval(a == 0); // expected-warning {{TRUE}}49  clang_analyzer_eval(b == 1); // expected-warning {{TRUE}}50  clang_analyzer_eval(c == 2); // expected-warning {{TRUE}}51  clang_analyzer_eval(d == 3); // expected-warning {{TRUE}}52}53 54void testDeleteDtor() {55  InlineDtor::cnt = 10;56  InlineDtor::dtorCalled = 0;57 58  InlineDtor *arr = new InlineDtor[4];59  delete[] arr;60 61  clang_analyzer_eval(a == 10); // expected-warning {{TRUE}}62  clang_analyzer_eval(b == 11); // expected-warning {{TRUE}}63  clang_analyzer_eval(c == 12); // expected-warning {{TRUE}}64  clang_analyzer_eval(d == 13); // expected-warning {{TRUE}}65}66 67struct MemberDtor {68  InlineDtor arr[4];69};70 71void testMemberDtor() {72  InlineDtor::cnt = 5;73  InlineDtor::dtorCalled = 0;74 75  MemberDtor *MD = new MemberDtor{};76  delete MD;77 78  clang_analyzer_eval(a == 5); // expected-warning {{TRUE}}79  clang_analyzer_eval(b == 6); // expected-warning {{TRUE}}80  clang_analyzer_eval(c == 7); // expected-warning {{TRUE}}81  clang_analyzer_eval(d == 8); // expected-warning {{TRUE}}82}83 84struct MultipleMemberDtor85{86  InlineDtor arr[4];87  InlineDtor arr2[4];88};89 90void testMultipleMemberDtor() {91  InlineDtor::cnt = 30;92  InlineDtor::dtorCalled = 0;93 94  MultipleMemberDtor *MD = new MultipleMemberDtor{};95  delete MD;96 97  clang_analyzer_eval(a == 34); // expected-warning {{TRUE}}98  clang_analyzer_eval(b == 35); // expected-warning {{TRUE}}99  clang_analyzer_eval(c == 36); // expected-warning {{TRUE}}100  clang_analyzer_eval(d == 37); // expected-warning {{TRUE}}101}102 103int EvalOrderArr[4];104 105struct EvalOrder106{107  int ctor = 0;108  static int dtorCalled;109  static int ctorCalled;110 111  EvalOrder() { ctor = ctorCalled++; };112 113  ~EvalOrder() { EvalOrderArr[ctor] = dtorCalled++; }114};115 116int EvalOrder::ctorCalled = 0;117int EvalOrder::dtorCalled = 0;118 119void dtorEvaluationOrder() {120  EvalOrder::ctorCalled = 0;121  EvalOrder::dtorCalled = 0;122  123  EvalOrder* eptr = new EvalOrder[4];124  delete[] eptr;125 126  clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}127  clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}128 129  clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}130  clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}131  clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}132  clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}133}134 135struct EmptyDtor {136  ~EmptyDtor(){};137};138 139struct DefaultDtor {140  ~DefaultDtor() = default;141};142 143// This function used to fail on an assertion.144void no_crash() {145  EmptyDtor* eptr = new EmptyDtor[4];146  delete[] eptr;147  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}148 149  DefaultDtor* dptr = new DefaultDtor[4];150  delete[] dptr;151  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}152}153 154// This snippet used to crash.155namespace crash2156{157  template <class _Tp> class unique_ptr {158  typedef _Tp *pointer;159  pointer __ptr_;160 161public:162  unique_ptr(pointer __p) : __ptr_(__p) {}163  ~unique_ptr() { reset(); }164  pointer get() { return __ptr_;}165  void reset() {}166};167 168struct S;169 170S *makeS();171int bar(S *x, S *y);172 173void foo() {174  unique_ptr<S> x(makeS()), y(makeS());175  bar(x.get(), y.get());176}177 178void bar() {179  foo();180  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}181}182 183} // namespace crash2184 185// This snippet used to crash.186namespace crash3187{188struct InlineDtor {189  ~InlineDtor() {}190};191struct MultipleMemberDtor192{193  InlineDtor arr[4];194  InlineDtor arr2[4];195};196 197void foo(){198  auto *arr = new MultipleMemberDtor[4];199  delete[] arr;200  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}201}202} // namespace crash3203 204namespace crash4 {205struct a {206  a *b;207};208struct c {209  a d;210  c();211  ~c() {212    for (a e = d;; e = *e.b)213      ;214  }215};216void f() { 217  c g; 218  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}219}220 221} // namespace crash4222 223namespace crash5 {224namespace std {225template <class _Tp> class unique_ptr {226  _Tp *__ptr_;227public:228  unique_ptr(_Tp *__p) : __ptr_(__p) {}229  ~unique_ptr() {}230};231} // namespace std232 233int SSL_use_certificate(int *arg) {234  std::unique_ptr<int> free_x509(arg);235  {236    if (SSL_use_certificate(arg)) {237      return 0;238    }239  }240  clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}241  return 1;242}243 244} // namespace crash5245 246void zeroLength(){247  InlineDtor::dtorCalled = 0;248 249  auto *arr = new InlineDtor[0];250  delete[] arr;251 252  auto *arr2 = new InlineDtor[2][0][2];253  delete[] arr2;254 255  auto *arr3 = new InlineDtor[0][2][2];256  delete[] arr3;257 258  auto *arr4 = new InlineDtor[2][2][0];259  delete[] arr4;260 261  clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}}262}263 264 265void evalOrderPrep() {266  EvalOrderArr[0] = 0;267  EvalOrderArr[1] = 0;268  EvalOrderArr[2] = 0;269  EvalOrderArr[3] = 0;270 271  EvalOrder::ctorCalled = 0;272  EvalOrder::dtorCalled = 0;273}274 275void multidimensionalPrep(){276  EvalOrder::ctorCalled = 0;277  EvalOrder::dtorCalled = 0;278 279  EvalOrder arr[2][2];280}281 282void multidimensional(){283  evalOrderPrep();284  multidimensionalPrep();285  286  clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}287  clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}288 289  clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}290  clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}291  clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}292  clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}293}294 295void multidimensionalHeap() {296  evalOrderPrep();297 298  auto* eptr = new EvalOrder[2][2];299  delete[] eptr;300 301  clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}302  clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}303 304  clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}305  clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}306  clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}307  clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}308}309 310struct MultiWrapper{311  EvalOrder arr[2][2];312};313 314void multidimensionalMember(){315  evalOrderPrep();316  317  auto* mptr = new MultiWrapper;318  delete mptr;319 320  clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}321  clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}322 323  clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}324  clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}325  clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}326  clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}327}328 329void *memset(void *, int, size_t);330void clang_analyzer_dumpElementCount(InlineDtor *);331 332void nonConstantRegionExtent(){333 334  InlineDtor::dtorCalled = 0;335 336  int x = 3;337  memset(&x, 1, sizeof(x));338 339  InlineDtor *arr = new InlineDtor[x];340  clang_analyzer_dumpElementCount(arr); // expected-warning {{conj_$0}}341  delete [] arr;342 343  //FIXME: This should be TRUE but memset also sets this344  // region to a conjured symbol.345  clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}} expected-warning {{FALSE}}346}347 348namespace crash6 {349 350struct NonTrivialItem {351  ~NonTrivialItem();352};353 354struct WeirdVec {355  void clear() {356    delete[] data;357    size = 0;358  }359  NonTrivialItem *data;360  unsigned size;361};362 363void top(int j) {364  WeirdVec *p = new WeirdVec;365 366  p[j].size = 0;367  delete[] p->data; // no-crash368}369 370template <typename T>371T make_unknown() {372  return reinterpret_cast<T>(static_cast<int>(0.404));373}374 375void directUnknownSymbol() {376  delete[] make_unknown<NonTrivialItem*>(); // no-crash377}378 379}380