1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLocalVarsChecker -verify %s 2 3 #include "mock-types.h" 4 #include "mock-system-header.h" 5 6 void someFunction(); 7 8 namespace raw_ptr { 9 void foo() { 10 CheckedObj *bar; 11 // FIXME: later on we might warn on uninitialized vars too 12 } 13 14 void bar(CheckedObj *) {} 15 } // namespace raw_ptr 16 17 namespace reference { 18 void foo_ref() { 19 CheckedObj automatic; 20 CheckedObj &bar = automatic; 21 // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 22 someFunction(); 23 bar.method(); 24 } 25 26 void foo_ref_trivial() { 27 CheckedObj automatic; 28 CheckedObj &bar = automatic; 29 } 30 31 void bar_ref(CheckedObj &) {} 32 } // namespace reference 33 34 namespace guardian_scopes { 35 void foo1() { 36 CheckedPtr<CheckedObj> foo; 37 { CheckedObj *bar = foo.get(); } 38 } 39 40 void foo2() { 41 CheckedPtr<CheckedObj> foo; 42 // missing embedded scope here 43 CheckedObj *bar = foo.get(); 44 // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 45 someFunction(); 46 bar->method(); 47 } 48 49 void foo3() { 50 CheckedPtr<CheckedObj> foo; 51 { 52 { CheckedObj *bar = foo.get(); } 53 } 54 } 55 56 void foo4() { 57 { 58 CheckedPtr<CheckedObj> foo; 59 { CheckedObj *bar = foo.get(); } 60 } 61 } 62 63 void foo5() { 64 CheckedPtr<CheckedObj> foo; 65 auto* bar = foo.get(); 66 bar->trivial(); 67 } 68 69 void foo6() { 70 CheckedPtr<CheckedObj> foo; 71 auto* bar = foo.get(); 72 // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 73 bar->method(); 74 } 75 76 struct SelfReferencingStruct { 77 SelfReferencingStruct* ptr; 78 CheckedObj* obj { nullptr }; 79 }; 80 81 void foo7(CheckedObj* obj) { 82 SelfReferencingStruct bar = { &bar, obj }; 83 bar.obj->method(); 84 } 85 86 } // namespace guardian_scopes 87 88 namespace auto_keyword { 89 class Foo { 90 CheckedObj *provide_ref_ctnbl(); 91 92 void evil_func() { 93 CheckedObj *bar = provide_ref_ctnbl(); 94 // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 95 auto *baz = provide_ref_ctnbl(); 96 // expected-warning@-1{{Local variable 'baz' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 97 auto *baz2 = this->provide_ref_ctnbl(); 98 // expected-warning@-1{{Local variable 'baz2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 99 [[clang::suppress]] auto *baz_suppressed = provide_ref_ctnbl(); // no-warning 100 } 101 102 void func() { 103 CheckedObj *bar = provide_ref_ctnbl(); 104 // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 105 if (bar) 106 bar->method(); 107 } 108 }; 109 } // namespace auto_keyword 110 111 namespace guardian_casts { 112 void foo1() { 113 CheckedPtr<CheckedObj> foo; 114 { 115 CheckedObj *bar = downcast<CheckedObj>(foo.get()); 116 bar->method(); 117 } 118 foo->method(); 119 } 120 121 void foo2() { 122 CheckedPtr<CheckedObj> foo; 123 { 124 CheckedObj *bar = 125 static_cast<CheckedObj *>(downcast<CheckedObj>(foo.get())); 126 someFunction(); 127 } 128 } 129 } // namespace guardian_casts 130 131 namespace guardian_ref_conversion_operator { 132 void foo() { 133 CheckedRef<CheckedObj> rc; 134 { 135 CheckedObj &rr = rc; 136 rr.method(); 137 someFunction(); 138 } 139 } 140 } // namespace guardian_ref_conversion_operator 141 142 namespace ignore_for_if { 143 CheckedObj *provide_ref_ctnbl() { return nullptr; } 144 145 void foo() { 146 // no warnings 147 if (CheckedObj *a = provide_ref_ctnbl()) 148 a->trivial(); 149 for (CheckedObj *b = provide_ref_ctnbl(); b != nullptr;) 150 b->trivial(); 151 CheckedObj *array[1]; 152 for (CheckedObj *c : array) 153 c->trivial(); 154 while (CheckedObj *d = provide_ref_ctnbl()) 155 d->trivial(); 156 do { 157 CheckedObj *e = provide_ref_ctnbl(); 158 e->trivial(); 159 } while (1); 160 someFunction(); 161 } 162 163 void bar() { 164 if (CheckedObj *a = provide_ref_ctnbl()) { 165 // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 166 a->method(); 167 } 168 for (CheckedObj *b = provide_ref_ctnbl(); b != nullptr;) { 169 // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 170 b->method(); 171 } 172 CheckedObj *array[1]; 173 for (CheckedObj *c : array) { 174 // expected-warning@-1{{Local variable 'c' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 175 c->method(); 176 } 177 178 while (CheckedObj *d = provide_ref_ctnbl()) { 179 // expected-warning@-1{{Local variable 'd' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 180 d->method(); 181 } 182 do { 183 CheckedObj *e = provide_ref_ctnbl(); 184 // expected-warning@-1{{Local variable 'e' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 185 e->method(); 186 } while (1); 187 someFunction(); 188 } 189 190 } // namespace ignore_for_if 191 192 namespace ignore_system_headers { 193 194 CheckedObj *provide_checkable(); 195 196 void system_header() { 197 localVar<CheckedObj>(provide_checkable); 198 } 199 200 } // ignore_system_headers 201 202 namespace conditional_op { 203 CheckedObj *provide_checkable(); 204 bool bar(); 205 206 void foo() { 207 CheckedObj *a = bar() ? nullptr : provide_checkable(); 208 // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 209 CheckedPtr<CheckedObj> b = provide_checkable(); 210 { 211 CheckedObj* c = bar() ? nullptr : b.get(); 212 c->method(); 213 CheckedObj* d = bar() ? b.get() : nullptr; 214 d->method(); 215 } 216 } 217 218 } // namespace conditional_op 219 220 namespace local_assignment_basic { 221 222 CheckedObj *provide_checkable(); 223 224 void foo(CheckedObj* a) { 225 CheckedObj* b = a; 226 // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 227 if (b->trivial()) 228 b = provide_checkable(); 229 } 230 231 void bar(CheckedObj* a) { 232 CheckedObj* b; 233 // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 234 b = provide_checkable(); 235 } 236 237 void baz() { 238 CheckedPtr a = provide_checkable(); 239 { 240 CheckedObj* b = a.get(); 241 // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 242 b = provide_checkable(); 243 } 244 } 245 246 } // namespace local_assignment_basic 247 248 namespace local_assignment_to_parameter { 249 250 CheckedObj *provide_checkable(); 251 void someFunction(); 252 253 void foo(CheckedObj* a) { 254 a = provide_checkable(); 255 // expected-warning@-1{{Assignment to an unchecked parameter 'a' is unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 256 someFunction(); 257 a->method(); 258 } 259 260 } // namespace local_assignment_to_parameter 261 262 namespace local_assignment_to_static_local { 263 264 CheckedObj *provide_checkable(); 265 void someFunction(); 266 267 void foo() { 268 static CheckedObj* a = nullptr; 269 // expected-warning@-1{{Static local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 270 a = provide_checkable(); 271 someFunction(); 272 a->method(); 273 } 274 275 } // namespace local_assignment_to_static_local 276 277 namespace local_assignment_to_global { 278 279 CheckedObj *provide_ref_cntbl(); 280 void someFunction(); 281 282 CheckedObj* g_a = nullptr; 283 // expected-warning@-1{{Global variable 'local_assignment_to_global::g_a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 284 285 void foo() { 286 g_a = provide_ref_cntbl(); 287 someFunction(); 288 g_a->method(); 289 } 290 291 } // namespace local_assignment_to_global 292 293 namespace local_refcountable_checkable_object { 294 295 RefCountableAndCheckable* provide_obj(); 296 297 void local_raw_ptr() { 298 RefCountableAndCheckable* a = nullptr; 299 // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 300 a = provide_obj(); 301 a->method(); 302 } 303 304 void local_checked_ptr() { 305 RefPtr<RefCountableAndCheckable> a = nullptr; 306 a = provide_obj(); 307 a->method(); 308 } 309 310 void local_var_with_guardian_checked_ptr() { 311 RefPtr<RefCountableAndCheckable> a = provide_obj(); 312 { 313 auto* b = a.get(); 314 b->method(); 315 } 316 } 317 318 void local_var_with_guardian_checked_ptr_with_assignment() { 319 RefPtr<RefCountableAndCheckable> a = provide_obj(); 320 { 321 RefCountableAndCheckable* b = a.get(); 322 // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 323 b = provide_obj(); 324 b->method(); 325 } 326 } 327 328 void local_var_with_guardian_checked_ref() { 329 Ref<RefCountableAndCheckable> a = *provide_obj(); 330 { 331 RefCountableAndCheckable& b = a; 332 b.method(); 333 } 334 } 335 336 void static_var() { 337 static RefCountableAndCheckable* a = nullptr; 338 // expected-warning@-1{{Static local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} 339 a = provide_obj(); 340 } 341 342 } // namespace local_refcountable_checkable_object 343