Clang Project

clang_source_code/test/Analysis/inlining/path-notes.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 %s
2// 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-compare
3// RUN: cat %t.plist | %diff_plist %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 pointer value 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 actually
258  // 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