brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 17e25d9 Raw
264 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s2 3#include "mock-types.h"4 5namespace WTF {6 7  constexpr unsigned long notFound = static_cast<unsigned long>(-1);8 9  class String;10  class StringImpl;11 12  class StringView {13  public:14    StringView(const String&);15  private:16    RefPtr<StringImpl> m_impl;17  };18 19  class StringImpl {20  public:21    void ref() const { ++m_refCount; }22    void deref() const {23      if (!--m_refCount)24        delete this;25    }26 27    static constexpr unsigned s_flagIs8Bit = 1u << 0;28    bool is8Bit() const { return m_hashAndFlags & s_flagIs8Bit; }29    const char* characters8() const { return m_char8; }30    const short* characters16() const { return m_char16; }31    unsigned length() const { return m_length; }32    Ref<StringImpl> substring(unsigned position, unsigned length) const;33 34    unsigned long find(char) const;35    unsigned long find(StringView) const;36    unsigned long contains(StringView) const;37    unsigned long findIgnoringASCIICase(StringView) const;38 39    bool startsWith(StringView) const;40    bool startsWithIgnoringASCIICase(StringView) const;41    bool endsWith(StringView) const;42    bool endsWithIgnoringASCIICase(StringView) const;43 44  private:45    mutable unsigned m_refCount { 0 };46    unsigned m_length { 0 };47    union {48      const char* m_char8;49      const short* m_char16;50    };51    unsigned m_hashAndFlags { 0 };52  };53 54  class String {55  public:56    String() = default;57    String(StringImpl& impl) : m_impl(&impl) { }58    String(StringImpl* impl) : m_impl(impl) { }59    String(Ref<StringImpl>&& impl) : m_impl(impl.get()) { }60    StringImpl* impl() { return m_impl.get(); }61    unsigned length() const { return m_impl ? m_impl->length() : 0; }62    const char* characters8() const { return m_impl ? m_impl->characters8() : nullptr; }63    const short* characters16() const { return m_impl ? m_impl->characters16() : nullptr; }64 65    bool is8Bit() const { return !m_impl || m_impl->is8Bit(); }66 67    unsigned long find(char character) const { return m_impl ? m_impl->find(character) : notFound; }68    unsigned long find(StringView str) const { return m_impl ? m_impl->find(str) : notFound; }69    unsigned long findIgnoringASCIICase(StringView) const;70 71    bool contains(char character) const { return find(character) != notFound; }72    bool contains(StringView) const;73    bool containsIgnoringASCIICase(StringView) const;74 75    bool startsWith(StringView) const;76    bool startsWithIgnoringASCIICase(StringView) const;77    bool endsWith(StringView) const;78    bool endsWithIgnoringASCIICase(StringView) const;79 80    String substring(unsigned position, unsigned length) const81    {82      if (!m_impl)83        return { };84      if (!position && length >= m_impl->length())85        return *this;86      return m_impl->substring(position, length);87    }88 89  private:90    RefPtr<StringImpl> m_impl;91  };92 93  template <typename T>94  class HashSet {95  public:96    template <typename U> T* find(U&) const;97    template <typename U> bool contains(U&) const;98    unsigned size() { return m_size; }99    template <typename U> void add(U&) const;100    template <typename U> void remove(U&) const;101 102  private:103    T* m_table { nullptr };104    unsigned m_size { 0 };105  };106 107  template <typename T, typename S>108  class HashMap {109  public:110    struct Item {111      T key;112      S value;113    };114 115    template <typename U> Item* find(U&) const;116    template <typename U> bool contains(U&) const;117    template <typename U> S* get(U&) const;118    template <typename U> S* inlineGet(U&) const;119    template <typename U> void add(U&) const;120    template <typename U> void remove(U&) const;121 122  private:123    Item* m_table { nullptr };124  };125 126  template <typename T>127  class WeakHashSet {128  public:129    template <typename U> T* find(U&) const;130    template <typename U> bool contains(U&) const;131    template <typename U> void add(U&) const;132    template <typename U> void remove(U&) const;133  };134 135  template <typename T>136  class Vector {137  public:138    unsigned size() { return m_size; }139    T& at(unsigned i) { return m_buffer[i]; }140    T& operator[](unsigned i) { return m_buffer[i]; }141    template <typename U> unsigned find(U&);142    template <typename U> unsigned reverseFind(U&);143    template <typename U> bool contains(U&);144    template <typename MatchFunction> unsigned findIf(const MatchFunction& match)145    {146      for (unsigned i = 0; i < m_size; ++i) {147        if (match(at(i)))148          return i;149      }150      return static_cast<unsigned>(-1);151    }152    template <typename MatchFunction> unsigned reverseFindIf(const MatchFunction& match)153    {154      for (unsigned i = 0; i < m_size; ++i) {155        if (match(at(m_size - i)))156          return i;157      }158      return static_cast<unsigned>(-1);159    }160    template <typename MatchFunction> bool containsIf(const MatchFunction& match)161    {162      for (unsigned i = 0; i < m_size; ++i) {163        if (match(at(m_size - i)))164          return true;165      }166      return false;167    }168    template <typename U> void append(U&) const;169    template <typename U> void remove(U&) const;170 171  private:172    T* m_buffer { nullptr };173    unsigned m_size { 0 };174  };175 176}177 178using WTF::StringView;179using WTF::StringImpl;180using WTF::String;181using WTF::HashSet;182using WTF::HashMap;183using WTF::WeakHashSet;184using WTF::Vector;185 186class RefCounted {187public:188  void ref() const;189  void deref() const;190};191 192RefCounted* object();193StringImpl* strImpl();194String* str();195StringView strView();196 197void test() {198  strImpl()->is8Bit();199  strImpl()->characters8();200  strImpl()->characters16();201  strImpl()->length();202  strImpl()->substring(2, 4);203  strImpl()->find(strView());204  strImpl()->contains(strView());205  strImpl()->findIgnoringASCIICase(strView());206  strImpl()->startsWith(strView());207  strImpl()->startsWithIgnoringASCIICase(strView());208  strImpl()->endsWith(strView());209  strImpl()->endsWithIgnoringASCIICase(strView());210 211  str()->is8Bit();212  str()->characters8();213  str()->characters16();214  str()->length();215  str()->substring(2, 4);216  str()->find(strView());217  str()->contains(strView());218  str()->findIgnoringASCIICase(strView());219  str()->startsWith(strView());220  str()->startsWithIgnoringASCIICase(strView());221  str()->endsWith(strView());222  str()->endsWithIgnoringASCIICase(strView());223 224  HashSet<RefPtr<RefCounted>> set;225  set.find(*object());226  set.contains(*object());227  set.add(*object());228  // expected-warning@-1{{Call argument is uncounted and unsafe}}229  set.remove(*object());230  // expected-warning@-1{{Call argument is uncounted and unsafe}}231 232  HashMap<Ref<RefCounted>, unsigned> map;233  map.find(*object());234  map.contains(*object());235  map.inlineGet(*object());236  map.add(*object());237  // expected-warning@-1{{Call argument is uncounted and unsafe}}238  map.remove(*object());239  // expected-warning@-1{{Call argument is uncounted and unsafe}}240 241  WeakHashSet<Ref<RefCounted>> weakSet;242  weakSet.find(*object());243  weakSet.contains(*object());244  weakSet.add(*object());245  // expected-warning@-1{{Call argument is uncounted and unsafe}}246  weakSet.remove(*object());247  // expected-warning@-1{{Call argument is uncounted and unsafe}}248 249  Vector<Ref<RefCounted>> vector;250  vector.at(0);251  vector[0];252  vector.find(*object());253  vector.reverseFind(*object());254  vector.contains(*object());255  vector.append(*object());256  // expected-warning@-1{{Call argument is uncounted and unsafe}}257  vector.remove(*object());258  // expected-warning@-1{{Call argument is uncounted and unsafe}}259 260  auto* obj = object();261  vector.findIf([&](Ref<RefCounted> key) { return key.ptr() == obj; });262  vector.reverseFindIf([&](Ref<RefCounted> key) { return key.ptr() == obj; });263  vector.containsIf([&](Ref<RefCounted> key) { return key.ptr() == obj; });264}