brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.0 KiB · 136b635 Raw
378 lines · cpp
1// RUN: %clang_analyze_cc1\2// RUN:  -analyzer-checker=core,cplusplus.Move,alpha.cplusplus.SmartPtr,debug.ExprInspection\3// RUN:  -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\4// RUN:  -analyzer-output=text -std=c++20 %s -verify=expected5 6// RUN: %clang_analyze_cc1\7// RUN:  -analyzer-checker=core,cplusplus.Move,alpha.cplusplus.SmartPtr,debug.ExprInspection\8// RUN:  -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\9// RUN:  -analyzer-output=text -std=c++11 %s -verify=expected10 11#include "Inputs/system-header-simulator-cxx.h"12 13void clang_analyzer_eval(bool);14 15class A {16public:17  A(){};18  void foo();19};20 21A *return_null() {22  return nullptr;23}24 25void derefAfterDefaultCtr() {26  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}27  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}28  // expected-note@-1{{Dereference of null smart pointer 'P'}}29}30 31void derefAfterCtrWithNull() {32  A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}33  std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}}34  *P; // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}35  // expected-note@-1{{Dereference of null smart pointer 'P'}}36}37 38void derefAfterCtrWithNullVariable() {39  A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}40  std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}}41  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}42  // expected-note@-1{{Dereference of null smart pointer 'P'}}43}44 45void derefAfterRelease() {46  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}47  // FIXME: should mark region as uninteresting after release, so above note will not be there48  P.release(); // expected-note {{Smart pointer 'P' is released and set to null}}49  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}50  // expected-note@-1{{Dereference of null smart pointer 'P'}}51}52 53void derefAfterReset() {54  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}55  P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}56  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}57  // expected-note@-1{{Dereference of null smart pointer 'P'}}58}59 60void derefAfterResetWithNull() {61  A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}62  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}63  P.reset(NullInnerPtr); // expected-note {{Smart pointer 'P' reset using a null value}}64  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}65  // expected-note@-1{{Dereference of null smart pointer 'P'}}66}67 68// FIXME: Fix this test when support is added for tracking raw pointer69// and mark the smart pointer as interesting based on that and add tags.70void derefOnReleasedNullRawPtr() {71  std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null"72  A *AP = P.release(); // expected-note {{'AP' initialized to a null pointer value}}73  AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}}74  // expected-note@-1{{Called C++ object pointer is null}}75}76 77void derefOnSwappedNullPtr() {78  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}79  std::unique_ptr<A> PNull;80  P.swap(PNull);81  PNull->foo(); // No warning.82  (*P).foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}83  // expected-note@-1{{Dereference of null smart pointer 'P'}}84}85 86void derefOnStdSwappedNullPtr() {87  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}88  std::unique_ptr<A> PNull;89  std::swap(P, PNull);90  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}91  // expected-note@-1{{Dereference of null smart pointer 'P'}}92}93 94struct StructWithSmartPtr { // expected-note {{Default constructed smart pointer 'S.P' is null}}95  std::unique_ptr<A> P;96};97 98void derefAfterDefaultCtrInsideStruct() {99  StructWithSmartPtr S; // expected-note {{Calling implicit default constructor for 'StructWithSmartPtr'}}100  // expected-note@-1 {{Returning from default constructor for 'StructWithSmartPtr'}}101  S.P->foo(); // expected-warning {{Dereference of null smart pointer 'S.P' [alpha.cplusplus.SmartPtr]}}102  // expected-note@-1{{Dereference of null smart pointer 'S.P'}}103}104 105void noNoteTagsForNonInterestingRegion() {106  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}107  std::unique_ptr<A> P1; // No note.108  std::unique_ptr<A> P2; // No note.109  P1.release(); // No note.110  P1.reset(); // No note.111  P1.swap(P2); // No note.112  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}113  // expected-note@-1{{Dereference of null smart pointer 'P'}}114}115 116void derefOnRawPtrFromGetOnNullPtr() {117  std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null"118  P.get()->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}}119  // expected-note@-1 {{Called C++ object pointer is null}}120}121 122void derefOnRawPtrFromGetOnValidPtr() {123  std::unique_ptr<A> P(new A());124  P.get()->foo(); // No warning.125}126 127void derefOnRawPtrFromGetOnUnknownPtr(std::unique_ptr<A> P) {128  P.get()->foo(); // No warning.129}130 131void derefOnMovedFromValidPtr() {132  std::unique_ptr<A> PToMove(new A());  // expected-note {{Smart pointer 'PToMove' is constructed}}133  // FIXME: above note should go away once we fix marking region not interested. 134  std::unique_ptr<A> P;135  P = std::move(PToMove); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}136  PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}137  // expected-note@-1 {{Dereference of null smart pointer 'PToMove'}}138}139 140void derefOnMovedToNullPtr() {141  std::unique_ptr<A> PToMove(new A());142  std::unique_ptr<A> P;143  P = std::move(PToMove); // No note.144  P->foo(); // No warning.145}146 147void derefOnNullPtrGotMovedFromValidPtr() {148  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}149  // FIXME: above note should go away once we fix marking region not interested. 150  std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}151  P = std::move(PToMove); // expected-note {{A null pointer value is moved to 'P'}}152  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}153  // expected-note@-1 {{Dereference of null smart pointer 'P'}}154}155 156void derefOnMovedUnknownPtr(std::unique_ptr<A> PToMove) {157  std::unique_ptr<A> P;158  P = std::move(PToMove); // expected-note {{Smart pointer 'PToMove' is null after; previous value moved to 'P'}}159  PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}160  // expected-note@-1 {{Dereference of null smart pointer 'PToMove'}}161}162 163void derefOnAssignedNullPtrToNullSmartPtr() {164  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}165  P = nullptr; // expected-note {{Smart pointer 'P' is assigned to null}}166  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}167  // expected-note@-1 {{Dereference of null smart pointer 'P'}}168}169 170void derefOnAssignedZeroToNullSmartPtr() {171  std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}172  // FIXME: above note should go away once we fix marking region not interested. 173  P = 0; // expected-note {{Smart pointer 'P' is assigned to null}}174  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}175  // expected-note@-1 {{Dereference of null smart pointer 'P'}}176}177 178void derefMoveConstructedWithNullPtr() {179  std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}180  std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{A null pointer value is moved to 'P'}}181  P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}182  // expected-note@-1{{Dereference of null smart pointer 'P'}}183}184 185void derefValidPtrMovedToConstruct() {186  std::unique_ptr<A> PToMove(new A()); // expected-note {{Smart pointer 'PToMove' is constructed}}187  // FIXME: above note should go away once we fix marking region not interested. 188  std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}189  PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}190  // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}191}192 193void derefNullPtrMovedToConstruct() {194  std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}195  // FIXME: above note should go away once we fix marking region not interested. 196  std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}197  PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}198  // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}199}200 201void derefUnknownPtrMovedToConstruct(std::unique_ptr<A> PToMove) {202  std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after; previous value moved to 'P'}}203  PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}204  // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}205}206 207void derefConditionOnNullPtrFalseBranch() {208  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}209  if (P) { // expected-note {{Taking false branch}}210    P->foo(); // No warning.211  } else {212    P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}213    // expected-note@-1{{Dereference of null smart pointer 'P'}}214  }215}216 217void derefConditionOnNullPtrTrueBranch() {218  std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}219  if (!P) { // expected-note {{Taking true branch}}220    P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}221    // expected-note@-1{{Dereference of null smart pointer 'P'}}222  }223}224 225void derefConditionOnValidPtrTrueBranch() {226  std::unique_ptr<A> P(new A());227  std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}228  if (P) { // expected-note {{Taking true branch}}229    PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}230    // expected-note@-1{{Dereference of null smart pointer 'PNull'}}231  } else {232    PNull->foo(); // No warning233  }234}235 236void derefConditionOnValidPtrFalseBranch() {237  std::unique_ptr<A> P(new A());238  std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}239  if (!P) { // expected-note {{Taking false branch}}240    PNull->foo(); // No warning241  } else {242    PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}243    // expected-note@-1{{Dereference of null smart pointer 'PNull'}}244  }245}246 247void derefConditionOnNotValidPtr() {248  std::unique_ptr<A> P(new A());249  std::unique_ptr<A> PNull;250  if (!P)251    PNull->foo(); // No warning.252}253 254void derefConditionOnUnKnownPtrAssumeNull(std::unique_ptr<A> P) {255  std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}256  if (!P) { // expected-note {{Taking true branch}}257    // expected-note@-1{{Assuming smart pointer 'P' is null}}258    PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}259    // expected-note@-1{{Dereference of null smart pointer 'PNull'}}260  }261}262 263void derefConditionOnUnKnownPtrAssumeNonNull(std::unique_ptr<A> P) {264  std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}265  if (P) { // expected-note {{Taking true branch}}266    // expected-note@-1{{Assuming smart pointer 'P' is non-null}}267    PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}268    // expected-note@-1{{Dereference of null smart pointer 'PNull'}}269  }270}271 272void derefOnValidPtrAfterReset(std::unique_ptr<A> P) {273  P.reset(new A());274  if (!P)275    P->foo(); // No warning.276  else277    P->foo(); // No warning.278}279 280struct S {281  std::unique_ptr<int> P;282 283  void foo() {284    if (!P) { // No-note because foo() is pruned285      return;286    }287  }288 289  int callingFooWithNullPointer() {290    foo(); // No note on Calling 'S::foo'291    P.reset(new int(0)); // expected-note {{Assigning 0}}292    return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}293    // expected-note@-1 {{Division by zero}}294  }295 296  int callingFooWithValidPointer() {297    P.reset(new int(0)); // expected-note {{Assigning 0}}298    foo(); // No note on Calling 'S::foo'299    return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}300    // expected-note@-1 {{Division by zero}}301  }302 303  int callingFooWithUnknownPointer(std::unique_ptr<int> PUnknown) {304    P.swap(PUnknown);305    foo(); // No note on Calling 'S::foo'306    P.reset(new int(0)); // expected-note {{Assigning 0}}307    return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}308    // expected-note@-1 {{Division by zero}}309  }310};311 312void derefAfterBranchingOnUnknownInnerPtr(std::unique_ptr<A> P) {313  A *RP = P.get();314  if (!RP) { // expected-note {{Assuming 'RP' is null}}315    // expected-note@-1 {{Taking true branch}}316    P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}317    // expected-note@-1{{Dereference of null smart pointer 'P'}}318  }319}320 321void makeUniqueReturnsNonNullUniquePtr() {322  auto P = std::make_unique<A>();323  if (!P) {   // expected-note {{Taking false branch}}324    P->foo(); // should have no warning here, path is impossible325  }326  P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}327  // Now P is null328  if (!P) {329    // expected-note@-1 {{Taking true branch}}330    P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}331    // expected-note@-1{{Dereference of null smart pointer 'P'}}332  }333}334 335#if __cplusplus >= 202002L336 337void makeUniqueForOverwriteReturnsNullUniquePtr() {338  auto P = std::make_unique_for_overwrite<A>();339  if (!P) {   // expected-note {{Taking false branch}}340    P->foo(); // should have no warning here, path is impossible341  }342  P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}343  // Now P is null344  if (!P) {345    // expected-note@-1 {{Taking true branch}}346    P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}347    // expected-note@-1{{Dereference of null smart pointer 'P'}}348  }349}350 351#endif352 353struct G {354  int *p;355  G(int *p): p(p) {}356  ~G() { *p = 0; }357};358 359void foo() {360  int x = 1;361  {362    auto P = std::make_unique<G>(&x);363    // FIXME: There should not be a state split here, it should take the true path.364    clang_analyzer_eval(*P->p == 1); // expected-warning {{TRUE}}365    // expected-warning@-1 {{FALSE}}366    // expected-note@-2 {{Assuming the condition is true}}367    // expected-note@-3 {{Assuming the condition is false}}368    // expected-note@-4 {{TRUE}}369    // expected-note@-5 {{FALSE}}370    // expected-note@-6 {{Assuming the condition is false}}371  }372  // FIXME: Should be fixed when unique_ptr desctructors are373  // properly modelled. This includes modelling the call to374  // the destructor of the inner pointer type.375  clang_analyzer_eval(x == 0); // expected-warning {{FALSE}}376  // expected-note@-1 {{FALSE}}377}378