// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLocalVarsChecker -verify %s #include "mock-types.h" #include "mock-system-header.h" void someFunction(); namespace raw_ptr { void foo() { CheckedObj *bar; // FIXME: later on we might warn on uninitialized vars too } void bar(CheckedObj *) {} } // namespace raw_ptr namespace reference { void foo_ref() { CheckedObj automatic; CheckedObj &bar = automatic; // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} someFunction(); bar.method(); } void foo_ref_trivial() { CheckedObj automatic; CheckedObj &bar = automatic; } void bar_ref(CheckedObj &) {} } // namespace reference namespace guardian_scopes { void foo1() { CheckedPtr foo; { CheckedObj *bar = foo.get(); } } void foo2() { CheckedPtr foo; // missing embedded scope here CheckedObj *bar = foo.get(); // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} someFunction(); bar->method(); } void foo3() { CheckedPtr foo; { { CheckedObj *bar = foo.get(); } } } void foo4() { { CheckedPtr foo; { CheckedObj *bar = foo.get(); } } } void foo5() { CheckedPtr foo; auto* bar = foo.get(); bar->trivial(); } void foo6() { CheckedPtr foo; auto* bar = foo.get(); // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} bar->method(); } struct SelfReferencingStruct { SelfReferencingStruct* ptr; CheckedObj* obj { nullptr }; }; void foo7(CheckedObj* obj) { SelfReferencingStruct bar = { &bar, obj }; bar.obj->method(); } } // namespace guardian_scopes namespace auto_keyword { class Foo { CheckedObj *provide_ref_ctnbl(); void evil_func() { CheckedObj *bar = provide_ref_ctnbl(); // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} auto *baz = provide_ref_ctnbl(); // expected-warning@-1{{Local variable 'baz' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} auto *baz2 = this->provide_ref_ctnbl(); // expected-warning@-1{{Local variable 'baz2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} [[clang::suppress]] auto *baz_suppressed = provide_ref_ctnbl(); // no-warning } void func() { CheckedObj *bar = provide_ref_ctnbl(); // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} if (bar) bar->method(); } }; } // namespace auto_keyword namespace guardian_casts { void foo1() { CheckedPtr foo; { CheckedObj *bar = downcast(foo.get()); bar->method(); } foo->method(); } void foo2() { CheckedPtr foo; { CheckedObj *bar = static_cast(downcast(foo.get())); someFunction(); } } } // namespace guardian_casts namespace guardian_ref_conversion_operator { void foo() { CheckedRef rc; { CheckedObj &rr = rc; rr.method(); someFunction(); } } } // namespace guardian_ref_conversion_operator namespace ignore_for_if { CheckedObj *provide_ref_ctnbl() { return nullptr; } void foo() { // no warnings if (CheckedObj *a = provide_ref_ctnbl()) a->trivial(); for (CheckedObj *b = provide_ref_ctnbl(); b != nullptr;) b->trivial(); CheckedObj *array[1]; for (CheckedObj *c : array) c->trivial(); while (CheckedObj *d = provide_ref_ctnbl()) d->trivial(); do { CheckedObj *e = provide_ref_ctnbl(); e->trivial(); } while (1); someFunction(); } void bar() { if (CheckedObj *a = provide_ref_ctnbl()) { // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} a->method(); } for (CheckedObj *b = provide_ref_ctnbl(); b != nullptr;) { // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} b->method(); } CheckedObj *array[1]; for (CheckedObj *c : array) { // expected-warning@-1{{Local variable 'c' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} c->method(); } while (CheckedObj *d = provide_ref_ctnbl()) { // expected-warning@-1{{Local variable 'd' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} d->method(); } do { CheckedObj *e = provide_ref_ctnbl(); // expected-warning@-1{{Local variable 'e' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} e->method(); } while (1); someFunction(); } } // namespace ignore_for_if namespace ignore_system_headers { CheckedObj *provide_checkable(); void system_header() { localVar(provide_checkable); } } // ignore_system_headers namespace conditional_op { CheckedObj *provide_checkable(); bool bar(); void foo() { CheckedObj *a = bar() ? nullptr : provide_checkable(); // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} CheckedPtr b = provide_checkable(); { CheckedObj* c = bar() ? nullptr : b.get(); c->method(); CheckedObj* d = bar() ? b.get() : nullptr; d->method(); } } } // namespace conditional_op namespace local_assignment_basic { CheckedObj *provide_checkable(); void foo(CheckedObj* a) { CheckedObj* b = a; // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} if (b->trivial()) b = provide_checkable(); } void bar(CheckedObj* a) { CheckedObj* b; // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} b = provide_checkable(); } void baz() { CheckedPtr a = provide_checkable(); { CheckedObj* b = a.get(); // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} b = provide_checkable(); } } } // namespace local_assignment_basic namespace local_assignment_to_parameter { CheckedObj *provide_checkable(); void someFunction(); void foo(CheckedObj* a) { a = provide_checkable(); // expected-warning@-1{{Assignment to an unchecked parameter 'a' is unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} someFunction(); a->method(); } } // namespace local_assignment_to_parameter namespace local_assignment_to_static_local { CheckedObj *provide_checkable(); void someFunction(); void foo() { static CheckedObj* a = nullptr; // expected-warning@-1{{Static local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} a = provide_checkable(); someFunction(); a->method(); } } // namespace local_assignment_to_static_local namespace local_assignment_to_global { CheckedObj *provide_ref_cntbl(); void someFunction(); CheckedObj* g_a = nullptr; // expected-warning@-1{{Global variable 'local_assignment_to_global::g_a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} void foo() { g_a = provide_ref_cntbl(); someFunction(); g_a->method(); } } // namespace local_assignment_to_global namespace member_var { struct WrapperObj { CheckedObj checked; CheckedObj& checkedRef; void foo() { auto *a = &checked; a->method(); auto *b = &checkedRef; // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} b->method(); } void bar(WrapperObj& wrapper) { CheckedObj* ptr = &wrapper.checked; // expected-warning@-1{{Local variable 'ptr' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} ptr->method(); } }; } namespace local_refcountable_checkable_object { RefCountableAndCheckable* provide_obj(); void local_raw_ptr() { RefCountableAndCheckable* a = nullptr; // expected-warning@-1{{Local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} a = provide_obj(); a->method(); } void local_checked_ptr() { RefPtr a = nullptr; a = provide_obj(); a->method(); } void local_var_with_guardian_checked_ptr() { RefPtr a = provide_obj(); { auto* b = a.get(); b->method(); } } void local_var_with_guardian_checked_ptr_with_assignment() { RefPtr a = provide_obj(); { RefCountableAndCheckable* b = a.get(); // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} b = provide_obj(); b->method(); } } void local_var_with_guardian_checked_ref() { Ref a = *provide_obj(); { RefCountableAndCheckable& b = a; b.method(); } } void static_var() { static RefCountableAndCheckable* a = nullptr; // expected-warning@-1{{Static local variable 'a' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} a = provide_obj(); } } // namespace local_refcountable_checkable_object