1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedLocalVarsChecker -verify %s
2 
3 #include "mock-types.h"
4 
5 namespace raw_ptr {
foo()6 void foo() {
7   RefCountable *bar;
8   // FIXME: later on we might warn on uninitialized vars too
9 }
10 
bar(RefCountable *)11 void bar(RefCountable *) {}
12 } // namespace raw_ptr
13 
14 namespace reference {
foo_ref()15 void foo_ref() {
16   RefCountable automatic;
17   RefCountable &bar = automatic;
18   // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
19 }
20 
bar_ref(RefCountable &)21 void bar_ref(RefCountable &) {}
22 } // namespace reference
23 
24 namespace guardian_scopes {
foo1()25 void foo1() {
26   RefPtr<RefCountable> foo;
27   { RefCountable *bar = foo.get(); }
28 }
29 
foo2()30 void foo2() {
31   RefPtr<RefCountable> foo;
32   // missing embedded scope here
33   RefCountable *bar = foo.get();
34   // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
35 }
36 
foo3()37 void foo3() {
38   RefPtr<RefCountable> foo;
39   {
40     { RefCountable *bar = foo.get(); }
41   }
42 }
43 
foo4()44 void foo4() {
45   {
46     RefPtr<RefCountable> foo;
47     { RefCountable *bar = foo.get(); }
48   }
49 }
50 } // namespace guardian_scopes
51 
52 namespace auto_keyword {
53 class Foo {
provide_ref_ctnbl()54   RefCountable *provide_ref_ctnbl() { return nullptr; }
55 
evil_func()56   void evil_func() {
57     RefCountable *bar = provide_ref_ctnbl();
58     // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
59     auto *baz = provide_ref_ctnbl();
60     // expected-warning@-1{{Local variable 'baz' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
61     auto *baz2 = this->provide_ref_ctnbl();
62     // expected-warning@-1{{Local variable 'baz2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}
63   }
64 };
65 } // namespace auto_keyword
66 
67 namespace guardian_casts {
foo1()68 void foo1() {
69   RefPtr<RefCountable> foo;
70   { RefCountable *bar = downcast<RefCountable>(foo.get()); }
71 }
72 
foo2()73 void foo2() {
74   RefPtr<RefCountable> foo;
75   {
76     RefCountable *bar =
77         static_cast<RefCountable *>(downcast<RefCountable>(foo.get()));
78   }
79 }
80 } // namespace guardian_casts
81 
82 namespace guardian_ref_conversion_operator {
foo()83 void foo() {
84   Ref<RefCountable> rc;
85   { RefCountable &rr = rc; }
86 }
87 } // namespace guardian_ref_conversion_operator
88 
89 namespace ignore_for_if {
provide_ref_ctnbl()90 RefCountable *provide_ref_ctnbl() { return nullptr; }
91 
foo()92 void foo() {
93   // no warnings
94   if (RefCountable *a = provide_ref_ctnbl()) { }
95   for (RefCountable *a = provide_ref_ctnbl(); a != nullptr;) { }
96   RefCountable *array[1];
97   for (RefCountable *a : array) { }
98 }
99 } // namespace ignore_for_if
100