1
+ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
2
+
3
+ #include " mock-types.h"
4
+
5
+ namespace WTF {
6
+
7
+ template <typename T>
8
+ class HashSet {
9
+ public:
10
+ template <typename U> T* find (U&) const ;
11
+ template <typename U> bool contains (U&) const ;
12
+ unsigned size () { return m_size; }
13
+ template <typename U> void add (U&) const ;
14
+ template <typename U> void remove (U&) const ;
15
+
16
+ private:
17
+ T* m_table { nullptr };
18
+ unsigned m_size { 0 };
19
+ };
20
+
21
+ template <typename T, typename S>
22
+ class HashMap {
23
+ public:
24
+ struct Item {
25
+ T key;
26
+ S value;
27
+ };
28
+
29
+ template <typename U> Item* find (U&) const ;
30
+ template <typename U> bool contains (U&) const ;
31
+ template <typename U> S* get (U&) const ;
32
+ template <typename U> S* inlineGet (U&) const ;
33
+ template <typename U> void add (U&) const ;
34
+ template <typename U> void remove (U&) const ;
35
+
36
+ private:
37
+ Item* m_table { nullptr };
38
+ };
39
+
40
+ template <typename T>
41
+ class WeakHashSet {
42
+ public:
43
+ template <typename U> T* find (U&) const ;
44
+ template <typename U> bool contains (U&) const ;
45
+ template <typename U> void add (U&) const ;
46
+ template <typename U> void remove (U&) const ;
47
+ };
48
+
49
+ template <typename T>
50
+ class Vector {
51
+ public:
52
+ unsigned size () { return m_size; }
53
+ T& at (unsigned i) { return m_buffer[i]; }
54
+ T& operator [](unsigned i) { return m_buffer[i]; }
55
+ template <typename U> unsigned find (U&);
56
+ template <typename U> unsigned reverseFind (U&);
57
+ template <typename U> bool contains (U&);
58
+ template <typename MatchFunction> unsigned findIf (const MatchFunction& match)
59
+ {
60
+ for (unsigned i = 0 ; i < m_size; ++i) {
61
+ if (match (at (i)))
62
+ return i;
63
+ }
64
+ return static_cast <unsigned >(-1 );
65
+ }
66
+ template <typename MatchFunction> unsigned reverseFindIf (const MatchFunction& match)
67
+ {
68
+ for (unsigned i = 0 ; i < m_size; ++i) {
69
+ if (match (at (m_size - i)))
70
+ return i;
71
+ }
72
+ return static_cast <unsigned >(-1 );
73
+ }
74
+ template <typename MatchFunction> bool containsIf (const MatchFunction& match)
75
+ {
76
+ for (unsigned i = 0 ; i < m_size; ++i) {
77
+ if (match (at (m_size - i)))
78
+ return true ;
79
+ }
80
+ return false ;
81
+ }
82
+ template <typename U> void append (U&) const ;
83
+ template <typename U> void remove (U&) const ;
84
+
85
+ private:
86
+ T* m_buffer { nullptr };
87
+ unsigned m_size { 0 };
88
+ };
89
+
90
+ }
91
+
92
+ using WTF::HashSet;
93
+ using WTF::HashMap;
94
+ using WTF::WeakHashSet;
95
+ using WTF::Vector;
96
+
97
+ class RefCounted {
98
+ public:
99
+ void ref () const ;
100
+ void deref () const ;
101
+ };
102
+
103
+ RefCounted* object ();
104
+
105
+ void test () {
106
+ HashSet<RefPtr<RefCounted>> set;
107
+ set.find (*object ());
108
+ set.contains (*object ());
109
+ set.add (*object ());
110
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
111
+ set.remove (*object ());
112
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
113
+
114
+ HashMap<Ref<RefCounted>, unsigned > map;
115
+ map.find (*object ());
116
+ map.contains (*object ());
117
+ map.inlineGet (*object ());
118
+ map.add (*object ());
119
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
120
+ map.remove (*object ());
121
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
122
+
123
+ WeakHashSet<Ref<RefCounted>> weakSet;
124
+ weakSet.find (*object ());
125
+ weakSet.contains (*object ());
126
+ weakSet.add (*object ());
127
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
128
+ weakSet.remove (*object ());
129
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
130
+
131
+ Vector<Ref<RefCounted>> vector;
132
+ vector.at (0 );
133
+ vector[0 ];
134
+ vector.find (*object ());
135
+ vector.reverseFind (*object ());
136
+ vector.contains (*object ());
137
+ vector.append (*object ());
138
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
139
+ vector.remove (*object ());
140
+ // expected-warning@-1{{Call argument is uncounted and unsafe}}
141
+
142
+ auto * obj = object ();
143
+ vector.findIf ([&](Ref<RefCounted> key) { return key.ptr () == obj; });
144
+ vector.reverseFindIf ([&](Ref<RefCounted> key) { return key.ptr () == obj; });
145
+ vector.containsIf ([&](Ref<RefCounted> key) { return key.ptr () == obj; });
146
+ }
0 commit comments