brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 1a8bde2 Raw
443 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s2 3#include "mock-types.h"4 5RefCountable* provide();6void consume_refcntbl(RefCountable*);7void some_function();8 9namespace simple {10  void foo() {11    consume_refcntbl(provide());12    // expected-warning@-1{{Call argument is uncounted and unsafe}}13  }14 15  // Test that the checker works with [[clang::suppress]].16  void foo_suppressed() {17    [[clang::suppress]]18    consume_refcntbl(provide()); // no-warning19  }20}21 22namespace multi_arg {23  void consume_refcntbl(int, RefCountable* foo, bool);24  void foo() {25    consume_refcntbl(42, provide(), true);26    // expected-warning@-1{{Call argument for parameter 'foo' is uncounted and unsafe}}27  }28}29 30namespace ref_counted {31  Ref<RefCountable> provide_ref_counted() { return Ref<RefCountable>{}; }32  void consume_ref_counted(Ref<RefCountable>) {}33 34  void foo() {35    consume_refcntbl(provide_ref_counted().ptr());36    // no warning37  }38}39 40namespace methods {41  struct Consumer {42    void consume_ptr(RefCountable* ptr);43    void consume_ref(const RefCountable& ref);44  };45 46  void foo() {47    Consumer c;48 49    c.consume_ptr(provide());50    // expected-warning@-1{{Call argument for parameter 'ptr' is uncounted and unsafe}}51    c.consume_ref(*provide());52    // expected-warning@-1{{Call argument for parameter 'ref' is uncounted and unsafe}}53  }54 55  void foo2() {56    struct Consumer {57      void consume(RefCountable*) { some_function(); }58      void whatever() {59        consume(provide());60        // expected-warning@-1{{Call argument is uncounted and unsafe}}61      }62    };63  }64 65  void foo3() {66    struct Consumer {67      void consume(RefCountable*) { some_function(); }68      void whatever() {69        this->consume(provide());70        // expected-warning@-1{{Call argument is uncounted and unsafe}}71      }72    };73  }74}75 76namespace casts {77  RefCountable* downcast(RefCountable*);78 79  void foo() {80    consume_refcntbl(provide());81    // expected-warning@-1{{Call argument is uncounted and unsafe}}82 83    consume_refcntbl(static_cast<RefCountable*>(provide()));84    // expected-warning@-1{{Call argument is uncounted and unsafe}}85 86    consume_refcntbl(dynamic_cast<RefCountable*>(provide()));87    // expected-warning@-1{{Call argument is uncounted and unsafe}}88 89    consume_refcntbl(const_cast<RefCountable*>(provide()));90    // expected-warning@-1{{Call argument is uncounted and unsafe}}91 92    consume_refcntbl(reinterpret_cast<RefCountable*>(provide()));93    // expected-warning@-1{{Call argument is uncounted and unsafe}}94 95    consume_refcntbl(downcast(provide()));96    // expected-warning@-1{{Call argument is uncounted and unsafe}}97 98    consume_refcntbl(99      static_cast<RefCountable*>(100        downcast(101          static_cast<RefCountable*>(102            provide()103          )104        )105      )106    );107    // expected-warning@-8{{Call argument is uncounted and unsafe}}108  }109}110 111namespace null_ptr {112  void foo_ref() {113    consume_refcntbl(nullptr);114    consume_refcntbl(0);115  }116}117 118namespace ref_counted_lookalike {119  struct Decoy {120    RefCountable* get();121  };122 123  void foo() {124    Decoy D;125 126    consume_refcntbl(D.get());127    // expected-warning@-1{{Call argument is uncounted and unsafe}}128  }129}130 131namespace Ref_to_reference_conversion_operator {132  template<typename T> struct Ref {133    Ref() = default;134    Ref(T*) { }135    T* get() { return nullptr; }136    operator T& () { return t; }137    T t;138  };139 140  void consume_ref(RefCountable&) {}141 142  void foo() {143    Ref<RefCountable> bar;144    consume_ref(bar);145  }146}147 148namespace param_formarding_function {149  void consume_ref_countable_ref(RefCountable&);150  void consume_ref_countable_ptr(RefCountable*);151 152  namespace ptr {153    void foo(RefCountable* param) {154      consume_ref_countable_ptr(param);155    }156  }157 158  namespace ref {159    void foo(RefCountable& param) {160      consume_ref_countable_ref(param);161    }162  }163 164  namespace ref_deref_operators {165    void foo_ref(RefCountable& param) {166      consume_ref_countable_ptr(&param);167    }168 169    void foo_ptr(RefCountable* param) {170      consume_ref_countable_ref(*param);171    }172  }173 174  namespace casts {175 176  RefCountable* downcast(RefCountable*);177  template<class T> T* bitwise_cast(T*);178  template<class T> T* bit_cast(T*);179 180  void foo(RefCountable* param) {181    consume_ref_countable_ptr(downcast(param));182    consume_ref_countable_ptr(bitwise_cast(param));183    consume_ref_countable_ptr(bit_cast(param));184   }185  }186}187 188namespace param_formarding_lambda {189  auto consume_ref_countable_ref = [](RefCountable&) { some_function(); };190  auto consume_ref_countable_ptr = [](RefCountable*) { some_function(); };191 192  namespace ptr {193    void foo(RefCountable* param) {194      consume_ref_countable_ptr(param);195    }196  }197 198  namespace ref {199    void foo(RefCountable& param) {200      consume_ref_countable_ref(param);201    }202  }203 204  namespace ref_deref_operators {205    void foo_ref(RefCountable& param) {206      consume_ref_countable_ptr(&param);207    }208 209    void foo_ptr(RefCountable* param) {210      consume_ref_countable_ref(*param);211    }212  }213 214  namespace casts {215 216  RefCountable* downcast(RefCountable*) { return nullptr; }217 218  template<class T>219  T* bitwise_cast(T*) { return nullptr; }220 221    void foo(RefCountable* param) {222      consume_ref_countable_ptr(downcast(param));223      consume_ref_countable_ptr(bitwise_cast(param));224    }225  }226}227 228namespace param_forwarding_method {229  struct methodclass {230    void consume_ref_countable_ref(RefCountable&) {};231    static void consume_ref_countable_ptr(RefCountable*) {};232  };233 234  namespace ptr {235    void foo(RefCountable* param) {236      methodclass::consume_ref_countable_ptr(param);237     }238  }239 240  namespace ref {241    void foo(RefCountable& param) {242      methodclass mc;243      mc.consume_ref_countable_ref(param);244     }245  }246 247  namespace ref_deref_operators {248    void foo_ref(RefCountable& param) {249      methodclass::consume_ref_countable_ptr(&param);250     }251 252    void foo_ptr(RefCountable* param) {253      methodclass mc;254      mc.consume_ref_countable_ref(*param);255     }256  }257 258  namespace casts {259 260  RefCountable* downcast(RefCountable*) { return nullptr; }261 262  template<class T>263  T* bitwise_cast(T*) { return nullptr; }264 265    void foo(RefCountable* param) {266      methodclass::consume_ref_countable_ptr(downcast(param));267       methodclass::consume_ref_countable_ptr(bitwise_cast(param));268     }269  }270}271 272namespace downcast {273  void consume_ref_countable(RefCountable*) {}274  RefCountable* downcast(RefCountable*) { return nullptr; }275 276  void foo() {277    RefPtr<RefCountable> bar;278    consume_ref_countable( downcast(bar.get()) );279  }280}281 282namespace string_impl {283  struct String {284    RefCountable* impl() { return nullptr; }285  };286 287  struct AtomString {288    RefCountable rc;289    RefCountable& impl() { return rc; }290  };291 292  void consume_ptr(RefCountable*) {}293  void consume_ref(RefCountable&) {}294 295  namespace simple {296    void foo() {297      String s;298      AtomString as;299      consume_ptr(s.impl());300      consume_ref(as.impl());301    }302  }303}304 305namespace default_arg {306  RefCountable* global;307 308  void function_with_default_arg(RefCountable* param = global);309  // expected-warning@-1{{Call argument for parameter 'param' is uncounted and unsafe}}310 311  void foo() {312    function_with_default_arg();313  }314}315 316namespace cxx_member_func {317  Ref<RefCountable> provideProtected();318  void foo() {319    provide()->trivial();320    provide()->method();321    // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}322    provideProtected()->method();323    (provideProtected())->method();324  };325}326 327namespace cxx_member_operator_call {328  // The hidden this-pointer argument without a corresponding parameter caused couple bugs in parameter <-> argument attribution.329  struct Foo {330    Foo& operator+(RefCountable* bad);331    friend Foo& operator-(Foo& lhs, RefCountable* bad);332    void operator()(RefCountable* bad);333  };334 335  RefCountable* global;336 337  void foo() {338    Foo f;339    f + global;340    // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}341    f - global;342    // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}343    f(global);344    // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}345  }346}347 348namespace call_with_ptr_on_ref {349  Ref<RefCountable> provideProtected();350  void bar(RefCountable* bad);351  bool baz();352  void foo(bool v) {353    bar(v ? nullptr : provideProtected().ptr());354    bar(baz() ? provideProtected().ptr() : nullptr);355    bar(v ? provide() : provideProtected().ptr());356    // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}357    bar(v ? provideProtected().ptr() : provide());358    // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}359  }360}361 362namespace call_with_explicit_construct_from_auto {363 364  struct Impl {365    void ref() const;366    void deref() const;367 368    static Ref<Impl> create();369  };370 371  template <typename T>372  struct ArgObj {373    T* t;374  };375 376  struct Object {377    Object();378    Object(Ref<Impl>&&);379 380    Impl* impl() const { return m_impl.get(); }381 382    static Object create(ArgObj<char>&) { return Impl::create(); }383    static void bar(Impl&);384 385  private:386    RefPtr<Impl> m_impl;387  };388 389  template<typename CharacterType> void foo()390  {391      auto result = Object::create(ArgObj<CharacterType> { });392      Object::bar(Ref { *result.impl() });393  }394 395}396 397namespace call_with_explicit_temporary_obj {398  void foo() {399    Ref { *provide() }->method();400    RefPtr { provide() }->method();401  }402  template <typename T>403  void bar() {404    Ref(*provide())->method();405    RefPtr(provide())->method();406  }407  void baz() {408    bar<int>();409  }410 411  class Foo {412    Ref<RefCountable> ensure();413    void foo() {414      Ref { ensure() }->method();415    }416  };417 418  void baz(Ref<RefCountable>&& arg) {419    Ref { arg }->method();420  }421}422 423namespace call_with_explicit_construct {424}425 426namespace call_with_adopt_ref {427  class Obj {428  public:429    void ref() const;430    void deref() const;431    void method();432  };433 434  // This is needed due to rdar://141692212.435  struct dummy {436    RefPtr<Obj> any;437  };438 439  void foo() {440    adoptRef(new Obj)->method();441  }442}443