[RISCV] Simplify usage of SplatPat_simm5_plus1. NFC (#125340)
[llvm-project.git] / clang / test / Analysis / Checkers / WebKit / uncounted-local-vars.cpp
blob52854cd10f68c7be43c9db1fb2c4fb506fdeaf4d
1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedLocalVarsChecker -verify %s
3 #include "mock-types.h"
4 #include "mock-system-header.h"
6 void someFunction();
8 namespace raw_ptr {
9 void foo() {
10 RefCountable *bar;
11 // FIXME: later on we might warn on uninitialized vars too
14 void bar(RefCountable *) {}
15 } // namespace raw_ptr
17 namespace reference {
18 void foo_ref() {
19 RefCountable automatic;
20 RefCountable &bar = automatic;
21 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
22 someFunction();
23 bar.method();
26 void foo_ref_trivial() {
27 RefCountable automatic;
28 RefCountable &bar = automatic;
31 void bar_ref(RefCountable &) {}
32 } // namespace reference
34 namespace guardian_scopes {
35 void foo1() {
36 RefPtr<RefCountable> foo;
37 { RefCountable *bar = foo.get(); }
40 void foo2() {
41 RefPtr<RefCountable> foo;
42 // missing embedded scope here
43 RefCountable *bar = foo.get();
44 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
45 someFunction();
46 bar->method();
49 void foo3() {
50 RefPtr<RefCountable> foo;
52 { RefCountable *bar = foo.get(); }
56 void foo4() {
58 RefPtr<RefCountable> foo;
59 { RefCountable *bar = foo.get(); }
63 void foo5() {
64 RefPtr<RefCountable> foo;
65 auto* bar = foo.get();
66 bar->trivial();
69 void foo6() {
70 RefPtr<RefCountable> foo;
71 auto* bar = foo.get();
72 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
73 bar->method();
76 struct SelfReferencingStruct {
77 SelfReferencingStruct* ptr;
78 RefCountable* obj { nullptr };
81 void foo7(RefCountable* obj) {
82 SelfReferencingStruct bar = { &bar, obj };
83 bar.obj->method();
86 void foo8(RefCountable* obj) {
87 RefPtr<RefCountable> foo;
89 RefCountable *bar = foo.get();
90 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
91 foo = nullptr;
92 bar->method();
94 RefPtr<RefCountable> baz;
96 RefCountable *bar = baz.get();
97 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
98 baz = obj;
99 bar->method();
101 foo = nullptr;
103 RefCountable *bar = foo.get();
104 // No warning. It's okay to mutate RefPtr in an outer scope.
105 bar->method();
107 foo = obj;
109 RefCountable *bar = foo.get();
110 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
111 foo.releaseNonNull();
112 bar->method();
115 RefCountable *bar = foo.get();
116 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
117 foo = obj ? obj : nullptr;
118 bar->method();
121 RefCountable *bar = foo->trivial() ? foo.get() : nullptr;
122 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
123 foo = nullptr;
124 bar->method();
128 void foo9(RefCountable& o) {
129 Ref<RefCountable> guardian(o);
131 RefCountable &bar = guardian.get();
132 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
133 guardian = o; // We don't detect that we're setting it to the same value.
134 bar.method();
137 RefCountable *bar = guardian.ptr();
138 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
139 Ref<RefCountable> other(*bar); // We don't detect other has the same value as guardian.
140 guardian.swap(other);
141 bar->method();
144 RefCountable *bar = guardian.ptr();
145 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
146 Ref<RefCountable> other(static_cast<Ref<RefCountable>&&>(guardian));
147 bar->method();
150 RefCountable *bar = guardian.ptr();
151 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
152 guardian.leakRef();
153 bar->method();
156 RefCountable *bar = guardian.ptr();
157 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
158 guardian = o.trivial() ? o : *bar;
159 bar->method();
163 } // namespace guardian_scopes
165 namespace auto_keyword {
166 class Foo {
167 RefCountable *provide_ref_ctnbl();
169 void evil_func() {
170 RefCountable *bar = provide_ref_ctnbl();
171 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
172 auto *baz = provide_ref_ctnbl();
173 // expected-warning@-1{{Local variable 'baz' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
174 auto *baz2 = this->provide_ref_ctnbl();
175 // expected-warning@-1{{Local variable 'baz2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
176 [[clang::suppress]] auto *baz_suppressed = provide_ref_ctnbl(); // no-warning
179 void func() {
180 RefCountable *bar = provide_ref_ctnbl();
181 // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
182 if (bar)
183 bar->method();
186 } // namespace auto_keyword
188 namespace guardian_casts {
189 void foo1() {
190 RefPtr<RefCountable> foo;
192 RefCountable *bar = downcast<RefCountable>(foo.get());
193 bar->method();
195 foo->method();
198 void foo2() {
199 RefPtr<RefCountable> foo;
201 RefCountable *bar =
202 static_cast<RefCountable *>(downcast<RefCountable>(foo.get()));
203 someFunction();
206 } // namespace guardian_casts
208 namespace guardian_ref_conversion_operator {
209 void foo() {
210 Ref<RefCountable> rc;
212 RefCountable &rr = rc;
213 rr.method();
214 someFunction();
217 } // namespace guardian_ref_conversion_operator
219 namespace ignore_for_if {
220 RefCountable *provide_ref_ctnbl() { return nullptr; }
222 void foo() {
223 // no warnings
224 if (RefCountable *a = provide_ref_ctnbl())
225 a->trivial();
226 for (RefCountable *b = provide_ref_ctnbl(); b != nullptr;)
227 b->trivial();
228 RefCountable *array[1];
229 for (RefCountable *c : array)
230 c->trivial();
231 while (RefCountable *d = provide_ref_ctnbl())
232 d->trivial();
233 do {
234 RefCountable *e = provide_ref_ctnbl();
235 e->trivial();
236 } while (1);
237 someFunction();
240 void bar() {
241 if (RefCountable *a = provide_ref_ctnbl()) {
242 // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
243 a->method();
245 for (RefCountable *b = provide_ref_ctnbl(); b != nullptr;) {
246 // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
247 b->method();
249 RefCountable *array[1];
250 for (RefCountable *c : array) {
251 // expected-warning@-1{{Local variable 'c' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
252 c->method();
255 while (RefCountable *d = provide_ref_ctnbl()) {
256 // expected-warning@-1{{Local variable 'd' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
257 d->method();
259 do {
260 RefCountable *e = provide_ref_ctnbl();
261 // expected-warning@-1{{Local variable 'e' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
262 e->method();
263 } while (1);
264 someFunction();
267 } // namespace ignore_for_if
269 namespace ignore_system_headers {
271 RefCountable *provide_ref_ctnbl();
273 void system_header() {
274 localVar<RefCountable>(provide_ref_ctnbl);
277 } // ignore_system_headers
279 namespace conditional_op {
280 RefCountable *provide_ref_ctnbl();
281 bool bar();
283 void foo() {
284 RefCountable *a = bar() ? nullptr : provide_ref_ctnbl();
285 // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
286 RefPtr<RefCountable> b = provide_ref_ctnbl();
288 RefCountable* c = bar() ? nullptr : b.get();
289 c->method();
290 RefCountable* d = bar() ? b.get() : nullptr;
291 d->method();
295 } // namespace conditional_op
297 namespace local_assignment_basic {
299 RefCountable *provide_ref_cntbl();
301 void foo(RefCountable* a) {
302 RefCountable* b = a;
303 // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
304 if (b->trivial())
305 b = provide_ref_cntbl();
308 void bar(RefCountable* a) {
309 RefCountable* b;
310 // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
311 b = provide_ref_cntbl();
314 void baz() {
315 RefPtr a = provide_ref_cntbl();
317 RefCountable* b = a.get();
318 // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
319 b = provide_ref_cntbl();
323 } // namespace local_assignment_basic
325 namespace local_assignment_to_parameter {
327 RefCountable *provide_ref_cntbl();
328 void someFunction();
330 void foo(RefCountable* a) {
331 a = provide_ref_cntbl();
332 // expected-warning@-1{{Assignment to an uncounted parameter 'a' is unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
333 someFunction();
334 a->method();
337 } // namespace local_assignment_to_parameter
339 namespace local_assignment_to_static_local {
341 RefCountable *provide_ref_cntbl();
342 void someFunction();
344 void foo() {
345 static RefCountable* a = nullptr;
346 // expected-warning@-1{{Static local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
347 a = provide_ref_cntbl();
348 someFunction();
349 a->method();
352 } // namespace local_assignment_to_static_local
354 namespace local_assignment_to_global {
356 RefCountable *provide_ref_cntbl();
357 void someFunction();
359 RefCountable* g_a = nullptr;
360 // expected-warning@-1{{Global variable 'local_assignment_to_global::g_a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
362 void foo() {
363 g_a = provide_ref_cntbl();
364 someFunction();
365 g_a->method();
368 } // namespace local_assignment_to_global
370 namespace local_refcountable_checkable_object {
372 RefCountableAndCheckable* provide_obj();
374 void local_raw_ptr() {
375 RefCountableAndCheckable* a = nullptr;
376 // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
377 a = provide_obj();
378 a->method();
381 void local_checked_ptr() {
382 CheckedPtr<RefCountableAndCheckable> a = nullptr;
383 a = provide_obj();
384 a->method();
387 void local_var_with_guardian_checked_ptr() {
388 CheckedPtr<RefCountableAndCheckable> a = provide_obj();
390 auto* b = a.get();
391 b->method();
395 void local_var_with_guardian_checked_ptr_with_assignment() {
396 CheckedPtr<RefCountableAndCheckable> a = provide_obj();
398 RefCountableAndCheckable* b = a.get();
399 // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
400 b = provide_obj();
401 b->method();
405 void local_var_with_guardian_checked_ref() {
406 CheckedRef<RefCountableAndCheckable> a = *provide_obj();
408 RefCountableAndCheckable& b = a;
409 b.method();
413 void static_var() {
414 static RefCountableAndCheckable* a = nullptr;
415 // expected-warning@-1{{Static local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
416 a = provide_obj();
419 } // namespace local_refcountable_checkable_object
421 namespace local_var_in_recursive_function {
423 struct TreeNode {
424 Ref<TreeNode> create() { return Ref(*new TreeNode); }
426 void ref() const { ++refCount; }
427 void deref() const {
428 if (!--refCount)
429 delete this;
432 int recursiveCost();
433 int recursiveWeight();
434 int weight();
436 int cost { 0 };
437 mutable unsigned refCount { 0 };
438 TreeNode* nextSibling { nullptr };
439 TreeNode* firstChild { nullptr };
442 int TreeNode::recursiveCost() {
443 // no warnings
444 unsigned totalCost = cost;
445 for (TreeNode* node = firstChild; node; node = node->nextSibling)
446 totalCost += recursiveCost();
447 return totalCost;
450 int TreeNode::recursiveWeight() {
451 unsigned totalCost = weight();
452 for (TreeNode* node = firstChild; node; node = node->nextSibling)
453 // expected-warning@-1{{Local variable 'node' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
454 totalCost += recursiveWeight();
455 return totalCost;
458 } // namespace local_var_in_recursive_function
460 namespace local_var_for_singleton {
461 RefCountable *singleton();
462 RefCountable *otherSingleton();
463 void foo() {
464 RefCountable* bar = singleton();
465 RefCountable* baz = otherSingleton();