[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / smart-ptr-text-output.cpp
blob136b63545e55f4d2fc287f7d6894c2474fd61095
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=expected
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=expected
11 #include "Inputs/system-header-simulator-cxx.h"
13 void clang_analyzer_eval(bool);
15 class A {
16 public:
17 A(){};
18 void foo();
21 A *return_null() {
22 return nullptr;
25 void 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'}}
31 void 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'}}
38 void 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'}}
45 void 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 there
48 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'}}
53 void 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'}}
60 void 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'}}
68 // FIXME: Fix this test when support is added for tracking raw pointer
69 // and mark the smart pointer as interesting based on that and add tags.
70 void 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}}
77 void 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'}}
86 void 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'}}
94 struct StructWithSmartPtr { // expected-note {{Default constructed smart pointer 'S.P' is null}}
95 std::unique_ptr<A> P;
98 void 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'}}
105 void 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'}}
116 void 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}}
122 void derefOnRawPtrFromGetOnValidPtr() {
123 std::unique_ptr<A> P(new A());
124 P.get()->foo(); // No warning.
127 void derefOnRawPtrFromGetOnUnknownPtr(std::unique_ptr<A> P) {
128 P.get()->foo(); // No warning.
131 void 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'}}
140 void 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.
147 void 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'}}
156 void 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'}}
163 void 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'}}
170 void 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'}}
178 void 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'}}
185 void 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'}}
193 void 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'}}
201 void 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'}}
207 void 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'}}
217 void 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'}}
225 void 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 warning
236 void 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 warning
241 } 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'}}
247 void derefConditionOnNotValidPtr() {
248 std::unique_ptr<A> P(new A());
249 std::unique_ptr<A> PNull;
250 if (!P)
251 PNull->foo(); // No warning.
254 void 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'}}
263 void 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'}}
272 void derefOnValidPtrAfterReset(std::unique_ptr<A> P) {
273 P.reset(new A());
274 if (!P)
275 P->foo(); // No warning.
276 else
277 P->foo(); // No warning.
280 struct S {
281 std::unique_ptr<int> P;
283 void foo() {
284 if (!P) { // No-note because foo() is pruned
285 return;
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}}
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}}
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}}
312 void 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'}}
321 void 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 impossible
326 P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}
327 // Now P is null
328 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'}}
335 #if __cplusplus >= 202002L
337 void 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 impossible
342 P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}
343 // Now P is null
344 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'}}
351 #endif
353 struct G {
354 int *p;
355 G(int *p): p(p) {}
356 ~G() { *p = 0; }
359 void foo() {
360 int x = 1;
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}}
372 // FIXME: Should be fixed when unique_ptr desctructors are
373 // properly modelled. This includes modelling the call to
374 // the destructor of the inner pointer type.
375 clang_analyzer_eval(x == 0); // expected-warning {{FALSE}}
376 // expected-note@-1 {{FALSE}}