brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.0 KiB · 3364637 Raw
495 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedLocalVarsChecker -verify %s2 3#include "mock-types.h"4#include "mock-system-header.h"5 6void someFunction();7 8namespace raw_ptr {9void foo() {10  RefCountable *bar;11  // FIXME: later on we might warn on uninitialized vars too12}13 14void bar(RefCountable *) {}15} // namespace raw_ptr16 17namespace reference {18void 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();24}25 26void foo_ref_trivial() {27  RefCountable automatic;28  RefCountable &bar = automatic;29}30 31void bar_ref(RefCountable &) {}32} // namespace reference33 34namespace guardian_scopes {35void foo1() {36  RefPtr<RefCountable> foo;37  { RefCountable *bar = foo.get(); }38}39 40void foo2() {41  RefPtr<RefCountable> foo;42  // missing embedded scope here43  RefCountable *bar = foo.get();44  // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}45  someFunction();46  bar->method();47}48 49void foo3() {50  RefPtr<RefCountable> foo;51  {52    { RefCountable *bar = foo.get(); }53  }54}55 56void foo4() {57  {58    RefPtr<RefCountable> foo;59    { RefCountable *bar = foo.get(); }60  }61}62 63void foo5() {64  RefPtr<RefCountable> foo;65  auto* bar = foo.get();66  bar->trivial();67}68 69void 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();74}75 76struct SelfReferencingStruct {77  SelfReferencingStruct* ptr;78  RefCountable* obj { nullptr };79};80 81void foo7(RefCountable* obj) {82  SelfReferencingStruct bar = { &bar, obj };83  bar.obj->method();84}85 86void foo8(RefCountable* obj) {87  RefPtr<RefCountable> foo;88  {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();93  }94  RefPtr<RefCountable> baz;95  {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();100  }101  foo = nullptr;102  {103    RefCountable *bar = foo.get();104    // No warning. It's okay to mutate RefPtr in an outer scope.105    bar->method();106  }107  foo = obj;108  {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();113  }114  {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();119  }120  {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    foo = (RefCountable *)0;125    bar->method();126  }127}128 129void foo9(RefCountable& o) {130  Ref<RefCountable> guardian(o);131  {132    RefCountable &bar = guardian.get();133    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}134    guardian = o; // We don't detect that we're setting it to the same value.135    bar.method();136  }137  {138    RefCountable *bar = guardian.ptr();139    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}140    Ref<RefCountable> other(*bar); // We don't detect other has the same value as guardian.141    guardian.swap(other);142    bar->method();143  }144  {145    RefCountable *bar = guardian.ptr();146    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}147    Ref<RefCountable> other(static_cast<Ref<RefCountable>&&>(guardian));148    bar->method();149  }150  {151    RefCountable *bar = guardian.ptr();152    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}153    guardian.leakRef();154    bar->method();155  }156  {157    RefCountable *bar = guardian.ptr();158    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}159    guardian = o.trivial() ? o : *bar;160    bar->method();161  }162}163 164} // namespace guardian_scopes165 166namespace auto_keyword {167class Foo {168  RefCountable *provide_ref_ctnbl();169 170  void evil_func() {171    RefCountable *bar = provide_ref_ctnbl();172    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}173    auto *baz = provide_ref_ctnbl();174    // expected-warning@-1{{Local variable 'baz' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}175    auto *baz2 = this->provide_ref_ctnbl();176    // expected-warning@-1{{Local variable 'baz2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}177    [[clang::suppress]] auto *baz_suppressed = provide_ref_ctnbl(); // no-warning178  }179 180  void func() {181    RefCountable *bar = provide_ref_ctnbl();182    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}183    if (bar)184      bar->method();185  }186};187} // namespace auto_keyword188 189namespace guardian_casts {190void foo1() {191  RefPtr<RefCountable> foo;192  {193    RefCountable *bar = downcast<RefCountable>(foo.get());194    bar->method();195  }196  foo->method();197}198 199void foo2() {200  RefPtr<RefCountable> foo;201  {202    RefCountable *bar =203        static_cast<RefCountable *>(downcast<RefCountable>(foo.get()));204    someFunction();205  }206}207} // namespace guardian_casts208 209namespace casts {210 211RefCountable* provide() { return nullptr; }212RefCountable* downcast(RefCountable*);213template<class T> T* bitwise_cast(T*);214template<class T> T* bit_cast(T*);215 216  void foo() {217    auto* cast1 = downcast(provide());218    auto* cast2 = bitwise_cast(provide());219    auto* cast3 = bit_cast(provide());220   }221} // namespace casts222 223namespace guardian_ref_conversion_operator {224void foo() {225  Ref<RefCountable> rc;226  {227    RefCountable &rr = rc;228    rr.method();229    someFunction();230  }231}232} // namespace guardian_ref_conversion_operator233 234namespace ignore_for_if {235RefCountable *provide_ref_ctnbl() { return nullptr; }236 237void foo() {238  // no warnings239  if (RefCountable *a = provide_ref_ctnbl())240    a->trivial();241  for (RefCountable *b = provide_ref_ctnbl(); b != nullptr;)242    b->trivial();243  RefCountable *array[1];244  for (RefCountable *c : array)245    c->trivial();246  while (RefCountable *d = provide_ref_ctnbl())247    d->trivial();248  do {249    RefCountable *e = provide_ref_ctnbl();250    e->trivial();251  } while (1);252  someFunction();253}254 255void bar() {256  if (RefCountable *a = provide_ref_ctnbl()) {257    // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}258    a->method();    259  }260  for (RefCountable *b = provide_ref_ctnbl(); b != nullptr;) {261    // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}262    b->method();263  }264  RefCountable *array[1];265  for (RefCountable *c : array) {266    // expected-warning@-1{{Local variable 'c' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}267    c->method();268  }269 270  while (RefCountable *d = provide_ref_ctnbl()) {271    // expected-warning@-1{{Local variable 'd' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}272    d->method();273  }274  do {275    RefCountable *e = provide_ref_ctnbl();276    // expected-warning@-1{{Local variable 'e' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}277    e->method();278  } while (1);279  someFunction();280}281 282} // namespace ignore_for_if283 284namespace ignore_system_headers {285 286RefCountable *provide_ref_ctnbl();287 288void system_header() {289  localVar<RefCountable>(provide_ref_ctnbl);290}291 292} // ignore_system_headers293 294namespace conditional_op {295RefCountable *provide_ref_ctnbl();296bool bar();297 298void foo() {299  RefCountable *a = bar() ? nullptr : provide_ref_ctnbl();300  // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}301  RefPtr<RefCountable> b = provide_ref_ctnbl();302  {303    RefCountable* c = bar() ? nullptr : b.get();304    c->method();305    RefCountable* d = bar() ? b.get() : nullptr;306    d->method();307  }308}309 310} // namespace conditional_op311 312namespace local_assignment_basic {313 314RefCountable *provide_ref_cntbl();315 316void foo(RefCountable* a) {317  RefCountable* b = a;318  // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}319  if (b->trivial())320    b = provide_ref_cntbl();321}322 323void bar(RefCountable* a) {324  RefCountable* b;325  // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}326  b = provide_ref_cntbl();327}328 329void baz() {330  RefPtr a = provide_ref_cntbl();331  {332    RefCountable* b = a.get();333    // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}334    b = provide_ref_cntbl();335  }336}337 338} // namespace local_assignment_basic339 340namespace local_assignment_to_parameter {341 342RefCountable *provide_ref_cntbl();343void someFunction();344 345void foo(RefCountable* a) {346  a = provide_ref_cntbl();347  // expected-warning@-1{{Assignment to an uncounted parameter 'a' is unsafe [alpha.webkit.UncountedLocalVarsChecker]}}348  someFunction();349  a->method();350}351 352} // namespace local_assignment_to_parameter353 354namespace local_assignment_to_static_local {355 356RefCountable *provide_ref_cntbl();357void someFunction();358 359void foo() {360  static RefCountable* a = nullptr;361  // expected-warning@-1{{Static local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}362  a = provide_ref_cntbl();363  someFunction();364  a->method();365}366 367} // namespace local_assignment_to_static_local368 369namespace local_assignment_to_global {370 371RefCountable *provide_ref_cntbl();372void someFunction();373 374RefCountable* g_a = nullptr;375// expected-warning@-1{{Global variable 'local_assignment_to_global::g_a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}376 377void foo() {378  g_a = provide_ref_cntbl();379  someFunction();380  g_a->method();381}382 383} // namespace local_assignment_to_global384 385namespace local_refcountable_checkable_object {386 387RefCountableAndCheckable* provide_obj();388 389void local_raw_ptr() {390  RefCountableAndCheckable* a = nullptr;391  // expected-warning@-1{{Local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}392  a = provide_obj();393  a->method();394}395 396void local_checked_ptr() {397  CheckedPtr<RefCountableAndCheckable> a = nullptr;398  a = provide_obj();399  a->method();400}401 402void local_var_with_guardian_checked_ptr() {403  CheckedPtr<RefCountableAndCheckable> a = provide_obj();404  {405    auto* b = a.get();406    b->method();407  }408}409 410void local_var_with_guardian_checked_ptr_with_assignment() {411  CheckedPtr<RefCountableAndCheckable> a = provide_obj();412  {413    RefCountableAndCheckable* b = a.get();414    // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}415    b = provide_obj();416    b->method();417  }418}419 420void local_var_with_guardian_checked_ref() {421  CheckedRef<RefCountableAndCheckable> a = *provide_obj();422  {423    RefCountableAndCheckable& b = a;424    b.method();425  }426}427 428void static_var() {429  static RefCountableAndCheckable* a = nullptr;430  // expected-warning@-1{{Static local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}431  a = provide_obj();432}433 434} // namespace local_refcountable_checkable_object435 436namespace local_var_in_recursive_function {437 438struct TreeNode {439  Ref<TreeNode> create() { return Ref(*new TreeNode); }440 441  void ref() const { ++refCount; }442  void deref() const {443    if (!--refCount)444      delete this;445  }446 447  int recursiveCost();448  int recursiveWeight();449  int weight();450 451  int cost { 0 };452  mutable unsigned refCount { 0 };453  TreeNode* nextSibling { nullptr };454  TreeNode* firstChild { nullptr };455};456 457int TreeNode::recursiveCost() {458  // no warnings459  unsigned totalCost = cost;460  for (TreeNode* node = firstChild; node; node = node->nextSibling)461    totalCost += recursiveCost();462  return totalCost;463}464 465int TreeNode::recursiveWeight() {466  unsigned totalCost = weight();467  for (TreeNode* node = firstChild; node; node = node->nextSibling)468    // expected-warning@-1{{Local variable 'node' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}469    totalCost += recursiveWeight();470  return totalCost;471}472 473} // namespace local_var_in_recursive_function474 475namespace local_var_for_singleton {476  RefCountable *singleton();477  RefCountable *otherSingleton();478  void foo() {479    RefCountable* bar = singleton();480    RefCountable* baz = otherSingleton();481  }482}483 484namespace virtual_function {485  struct SomeObject {486    virtual RefCountable* provide() { return nullptr; }487    virtual RefCountable* operator&() { return nullptr; }488  };489  void foo(SomeObject* obj) {490    auto* bar = obj->provide();491    // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}492    auto* baz = &*obj;493    // expected-warning@-1{{Local variable 'baz' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}}494  }495}