301 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 %s -o %t.plist -Wno-tautological-undefined-compare3// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/path-notes.cpp.plist -4 5class Foo {6public:7 static void use(int *p) {8 *p = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}9 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}10 }11 12 Foo(int *p) {13 use(p);14 // expected-note@-1 {{Passing null pointer value via 1st parameter 'p'}}15 // expected-note@-2 {{Calling 'Foo::use'}}16 }17};18 19static int *globalPtr;20 21class Bar {22public:23 ~Bar() {24 Foo f(globalPtr);25 // expected-note@-1 {{Passing null pointer value via 1st parameter 'p'}}26 // expected-note@-2 {{Calling constructor for 'Foo'}}27 }28};29 30void test() {31 Bar b;32 globalPtr = 0;33 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}34} // expected-note {{Calling '~Bar'}}35 36 37void testAnonymous() {38 class {39 public:40 void method(int *p) {41 *p = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}42 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}43 }44 } anonymous;45 46 anonymous.method(0);47 // expected-note@-1 {{Passing null pointer value via 1st parameter 'p'}}48 // expected-note@-2 {{Calling 'method'}}49}50 51 52// A simplified version of std::move.53template <typename T>54T &&move(T &obj) {55 return static_cast<T &&>(obj);56}57 58 59namespace defaulted {60 class Dereferencer {61 public:62 Dereferencer() {63 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}64 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}65 }66 67 Dereferencer(const Dereferencer &Other) {68 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}69 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}70 }71 72 Dereferencer(Dereferencer &&Other) {73 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}74 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}75 }76 77 void operator=(const Dereferencer &Other) {78 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}79 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}80 }81 82 void operator=(Dereferencer &&Other) {83 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}84 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}85 }86 87 ~Dereferencer() {88 *globalPtr = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'globalPtr')}}89 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'globalPtr')}}90 }91 };92 93 class Wrapper {94 Dereferencer d;95 };96 97 class MovableWrapper {98 Dereferencer d;99 public:100 MovableWrapper() = default;101 102 MovableWrapper(MovableWrapper &&Other) = default;103 // expected-note@-1 {{Calling move constructor for 'Dereferencer'}}104 105 MovableWrapper &operator=(MovableWrapper &&Other) = default;106 // expected-note@-1 {{Calling move assignment operator for 'Dereferencer'}}107 };108 109 void testDefaultConstruction() {110 globalPtr = 0;111 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}112 Wrapper w;113 // expected-note@-1 {{Calling implicit default constructor for 'Wrapper'}}114 // expected-note@-2 {{Calling default constructor for 'Dereferencer'}}115 }116 117 void testCopyConstruction(const Wrapper &input) {118 globalPtr = 0;119 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}120 Wrapper w{input};121 // expected-note@-1 {{Calling implicit copy constructor for 'Wrapper'}}122 // expected-note@-2 {{Calling copy constructor for 'Dereferencer'}}123 }124 125 void testMoveConstruction(MovableWrapper &&input) {126 globalPtr = 0;127 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}128 MovableWrapper w{move(input)};129 // expected-note@-1 {{Calling defaulted move constructor for 'MovableWrapper'}}130 }131 132 void testCopyAssignment(const Wrapper &input) {133 Wrapper w;134 globalPtr = 0;135 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}136 w = input;137 // expected-note@-1 {{Calling implicit copy assignment operator for 'Wrapper'}}138 // expected-note@-2 {{Calling copy assignment operator for 'Dereferencer'}}139 }140 141 void testMoveAssignment(MovableWrapper &&input) {142 MovableWrapper w;143 globalPtr = 0;144 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}145 w = move(input);146 // expected-note@-1 {{Calling defaulted move assignment operator for 'MovableWrapper'}}147 }148 149 void testDestruction() {150 Wrapper w;151 globalPtr = 0;152 // expected-note@-1 {{Null pointer value stored to 'globalPtr'}}153 }154 // expected-note@-1 {{Calling implicit destructor for 'Wrapper'}}155 // expected-note@-2 {{Calling '~Dereferencer'}}156}157 158namespace ReturnZeroNote {159 int getZero() {160 return 0;161 // expected-note@-1 {{Returning zero}}162 }163 164 const int &getZeroByRef() {165 static int zeroVar;166 zeroVar = 0;167 // expected-note@-1 {{The value 0 is assigned to 'zeroVar'}}168 return zeroVar;169 // expected-note@-1 {{Returning zero (reference to 'zeroVar')}}170 }171 172 void test() {173 int problem = 1 / getZero(); // expected-warning {{Division by zero}}174 // expected-note@-1 {{Calling 'getZero'}}175 // expected-note@-2 {{Returning from 'getZero'}}176 // expected-note@-3 {{Division by zero}}177 }178 179 void testRef() {180 int problem = 1 / getZeroByRef(); // expected-warning {{Division by zero}}181 // expected-note@-1 {{Calling 'getZeroByRef'}}182 // expected-note@-2 {{Returning from 'getZeroByRef'}}183 // expected-note@-3 {{Division by zero}}184 }185}186 187int &returnNullReference() {188 int *x = 0;189 // expected-note@-1 {{'x' initialized to a null pointer value}}190 return *x; // expected-warning{{Returning null reference}}191 // expected-note@-1 {{Returning null reference}}192}193 194struct FooWithInitializer {195 int *ptr;196 FooWithInitializer(int *p) : ptr(p) { // expected-note {{Null pointer value stored to 'f.ptr'}}197 *ptr = 1; // expected-note {{Dereference of null pointer (loaded from field 'ptr')}}198 // expected-warning@-1 {{Dereference of null pointer (loaded from field 'ptr')}}199 }200};201 202void testPathNoteOnInitializer() {203 int *p = 0; // expected-note {{'p' initialized to a null pointer value}}204 205 FooWithInitializer f(p); // expected-note {{Passing null pointer value via 1st parameter 'p'}}206 // expected-note@-1 {{Calling constructor for 'FooWithInitializer'}}207}208 209int testNonPrintableAssignment(int **p) {210 int *&y = *p; // expected-note {{'y' initialized here}}211 y = 0; // expected-note {{Storing null pointer value}}212 return *y; // expected-warning {{Dereference of null pointer (loaded from variable 'y')}}213 // expected-note@-1 {{Dereference of null pointer (loaded from variable 'y')}}214}215 216struct Base { int *x; };217struct Derived : public Base {};218 219void test(Derived d) {220 d.x = 0; //expected-note {{Null pointer value stored to 'd.x'}}221 *d.x = 1; // expected-warning {{Dereference of null pointer (loaded from field 'x')}}222 // expected-note@-1 {{Dereference of null pointer (loaded from field 'x')}}223}224 225struct Owner {226 struct Wrapper {227 int x;228 };229 Wrapper *arr;230 void testGetDerefExprOnMemberExprWithADot();231};232 233void Owner::testGetDerefExprOnMemberExprWithADot() {234 if (arr) // expected-note {{Assuming field 'arr' is null}}235 // expected-note@-1 {{Taking false branch}}236 ;237 arr[1].x = 1; //expected-warning {{Dereference of null pointer}}238 //expected-note@-1 {{Dereference of null pointer}}239}240 241void testGetDerefExprOnMemberExprWithADot() {242 Owner::Wrapper *arr; // expected-note {{'arr' declared without an initial value}}243 arr[2].x = 1; // expected-warning {{Dereference of undefined pointer value}}244 // expected-note@-1 {{Dereference of undefined pointer value}}245}246 247 248 249class A {250public:251 void bar() const {}252};253const A& testDeclRefExprToReferenceInGetDerefExpr(const A *ptr) {254 const A& val = *ptr; //expected-note {{'val' initialized here}}255 256 // This is not valid C++; if 'ptr' were null, creating 'ref' would be illegal.257 // However, this is not checked at runtime, so this branch is actually258 // possible.259 if (&val == 0) { //expected-note {{Assuming pointer value is null}}260 // expected-note@-1 {{Taking true branch}}261 val.bar(); // expected-warning {{Called C++ object pointer is null}}262 // expected-note@-1 {{Called C++ object pointer is null}}263 }264 265 return val;266}267 268int generateNoteOnDefaultArgument(int one, int two = 0) {269 return one/two; // expected-warning {{Division by zero}}270 // expected-note@-1 {{Division by zero}}271}272int callGenerateNoteOnDefaultArgument(int o) {273 return generateNoteOnDefaultArgument(o); //expected-note{{Calling 'generateNoteOnDefaultArgument'}}274 //expected-note@-1 {{Passing the value 0 via 2nd parameter 'two'}}275}276 277namespace PR17746 {278 class Inner {279 public:280 ~Inner() {281 *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}282 // expected-note@-1 {{Dereference of null pointer}}283 }284 };285 286 class Outer {287 public:288 Inner *inner;289 ~Outer() {290 delete inner;291 // expected-note@-1 {{Calling '~Inner'}}292 }293 };294 295 void test(Outer *outer) {296 delete outer;297 // expected-note@-1 {{Calling '~Outer'}}298 }299}300 301