================ @@ -0,0 +1,342 @@ +// 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<CheckedObj> foo; + { CheckedObj *bar = foo.get(); } +} + +void foo2() { + CheckedPtr<CheckedObj> 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<CheckedObj> foo; + { + { CheckedObj *bar = foo.get(); } + } +} + +void foo4() { + { + CheckedPtr<CheckedObj> foo; + { CheckedObj *bar = foo.get(); } + } +} + +void foo5() { + CheckedPtr<CheckedObj> foo; + auto* bar = foo.get(); + bar->trivial(); +} + +void foo6() { + CheckedPtr<CheckedObj> 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<CheckedObj> foo; + { + CheckedObj *bar = downcast<CheckedObj>(foo.get()); + bar->method(); + } + foo->method(); +} + +void foo2() { + CheckedPtr<CheckedObj> foo; + { + CheckedObj *bar = + static_cast<CheckedObj *>(downcast<CheckedObj>(foo.get())); + someFunction(); + } +} +} // namespace guardian_casts + +namespace guardian_ref_conversion_operator { +void foo() { + CheckedRef<CheckedObj> 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<CheckedObj>(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<CheckedObj> 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 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<RefCountableAndCheckable> a = nullptr; + a = provide_obj(); + a->method(); +} + +void local_var_with_guardian_checked_ptr() { + RefPtr<RefCountableAndCheckable> a = provide_obj(); + { + auto* b = a.get(); + b->method(); + } +} + +void local_var_with_guardian_checked_ptr_with_assignment() { + RefPtr<RefCountableAndCheckable> 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<RefCountableAndCheckable> 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 ---------------- t-rasmud wrote:
Do we expect a similar warning for assignments to struct members or class fields? https://github.com/llvm/llvm-project/pull/113708 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits