1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
3 #include "mock-types.h"
5 RefCountable
* provide();
6 void consume_refcntbl(RefCountable
*);
11 consume_refcntbl(provide());
12 // expected-warning@-1{{Call argument is uncounted and unsafe}}
15 // Test that the checker works with [[clang::suppress]].
16 void foo_suppressed() {
18 consume_refcntbl(provide()); // no-warning
23 void consume_refcntbl(int, RefCountable
* foo
, bool);
25 consume_refcntbl(42, provide(), true);
26 // expected-warning@-1{{Call argument for parameter 'foo' is uncounted and unsafe}}
30 namespace ref_counted
{
31 Ref
<RefCountable
> provide_ref_counted() { return Ref
<RefCountable
>{}; }
32 void consume_ref_counted(Ref
<RefCountable
>) {}
35 consume_refcntbl(provide_ref_counted().ptr());
42 void consume_ptr(RefCountable
* ptr
);
43 void consume_ref(const RefCountable
& ref
);
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}}
57 void consume(RefCountable
*) { some_function(); }
60 // expected-warning@-1{{Call argument is uncounted and unsafe}}
67 void consume(RefCountable
*) { some_function(); }
69 this->consume(provide());
70 // expected-warning@-1{{Call argument is uncounted and unsafe}}
77 RefCountable
* downcast(RefCountable
*);
80 consume_refcntbl(provide());
81 // expected-warning@-1{{Call argument is uncounted and unsafe}}
83 consume_refcntbl(static_cast<RefCountable
*>(provide()));
84 // expected-warning@-1{{Call argument is uncounted and unsafe}}
86 consume_refcntbl(dynamic_cast<RefCountable
*>(provide()));
87 // expected-warning@-1{{Call argument is uncounted and unsafe}}
89 consume_refcntbl(const_cast<RefCountable
*>(provide()));
90 // expected-warning@-1{{Call argument is uncounted and unsafe}}
92 consume_refcntbl(reinterpret_cast<RefCountable
*>(provide()));
93 // expected-warning@-1{{Call argument is uncounted and unsafe}}
95 consume_refcntbl(downcast(provide()));
96 // expected-warning@-1{{Call argument is uncounted and unsafe}}
99 static_cast<RefCountable
*>(
101 static_cast<RefCountable
*>(
107 // expected-warning@-8{{Call argument is uncounted and unsafe}}
113 consume_refcntbl(nullptr);
118 namespace ref_counted_lookalike
{
126 consume_refcntbl(D
.get());
127 // expected-warning@-1{{Call argument is uncounted and unsafe}}
131 namespace Ref_to_reference_conversion_operator
{
132 template<typename T
> struct Ref
{
135 T
* get() { return nullptr; }
136 operator T
& () { return t
; }
140 void consume_ref(RefCountable
&) {}
143 Ref
<RefCountable
> bar
;
148 namespace param_formarding_function
{
149 void consume_ref_countable_ref(RefCountable
&);
150 void consume_ref_countable_ptr(RefCountable
*);
153 void foo(RefCountable
* param
) {
154 consume_ref_countable_ptr(param
);
159 void foo(RefCountable
& param
) {
160 consume_ref_countable_ref(param
);
164 namespace ref_deref_operators
{
165 void foo_ref(RefCountable
& param
) {
166 consume_ref_countable_ptr(¶m
);
169 void foo_ptr(RefCountable
* param
) {
170 consume_ref_countable_ref(*param
);
176 RefCountable
* downcast(RefCountable
*) { return nullptr; }
179 T
* bitwise_cast(T
*) { return nullptr; }
181 void foo(RefCountable
* param
) {
182 consume_ref_countable_ptr(downcast(param
));
183 consume_ref_countable_ptr(bitwise_cast(param
));
188 namespace param_formarding_lambda
{
189 auto consume_ref_countable_ref
= [](RefCountable
&) { some_function(); };
190 auto consume_ref_countable_ptr
= [](RefCountable
*) { some_function(); };
193 void foo(RefCountable
* param
) {
194 consume_ref_countable_ptr(param
);
199 void foo(RefCountable
& param
) {
200 consume_ref_countable_ref(param
);
204 namespace ref_deref_operators
{
205 void foo_ref(RefCountable
& param
) {
206 consume_ref_countable_ptr(¶m
);
209 void foo_ptr(RefCountable
* param
) {
210 consume_ref_countable_ref(*param
);
216 RefCountable
* downcast(RefCountable
*) { return nullptr; }
219 T
* bitwise_cast(T
*) { return nullptr; }
221 void foo(RefCountable
* param
) {
222 consume_ref_countable_ptr(downcast(param
));
223 consume_ref_countable_ptr(bitwise_cast(param
));
228 namespace param_forwarding_method
{
230 void consume_ref_countable_ref(RefCountable
&) {};
231 static void consume_ref_countable_ptr(RefCountable
*) {};
235 void foo(RefCountable
* param
) {
236 methodclass::consume_ref_countable_ptr(param
);
241 void foo(RefCountable
& param
) {
243 mc
.consume_ref_countable_ref(param
);
247 namespace ref_deref_operators
{
248 void foo_ref(RefCountable
& param
) {
249 methodclass::consume_ref_countable_ptr(¶m
);
252 void foo_ptr(RefCountable
* param
) {
254 mc
.consume_ref_countable_ref(*param
);
260 RefCountable
* downcast(RefCountable
*) { return nullptr; }
263 T
* bitwise_cast(T
*) { return nullptr; }
265 void foo(RefCountable
* param
) {
266 methodclass::consume_ref_countable_ptr(downcast(param
));
267 methodclass::consume_ref_countable_ptr(bitwise_cast(param
));
273 void consume_ref_countable(RefCountable
*) {}
274 RefCountable
* downcast(RefCountable
*) { return nullptr; }
277 RefPtr
<RefCountable
> bar
;
278 consume_ref_countable( downcast(bar
.get()) );
282 namespace string_impl
{
284 RefCountable
* impl() { return nullptr; }
289 RefCountable
& impl() { return rc
; }
292 void consume_ptr(RefCountable
*) {}
293 void consume_ref(RefCountable
&) {}
299 consume_ptr(s
.impl());
300 consume_ref(as
.impl());
305 namespace default_arg
{
306 RefCountable
* global
;
308 void function_with_default_arg(RefCountable
* param
= global
);
309 // expected-warning@-1{{Call argument for parameter 'param' is uncounted and unsafe}}
312 function_with_default_arg();
316 namespace cxx_member_func
{
317 Ref
<RefCountable
> provideProtected();
319 provide()->trivial();
321 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}
322 provideProtected()->method();
323 (provideProtected())->method();
327 namespace cxx_member_operator_call
{
328 // The hidden this-pointer argument without a corresponding parameter caused couple bugs in parameter <-> argument attribution.
330 Foo
& operator+(RefCountable
* bad
);
331 friend Foo
& operator-(Foo
& lhs
, RefCountable
* bad
);
332 void operator()(RefCountable
* bad
);
335 RefCountable
* global
;
340 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}
342 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}
344 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}
348 namespace call_with_ptr_on_ref
{
349 Ref
<RefCountable
> provideProtected();
350 void bar(RefCountable
* bad
);
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}}
362 namespace call_with_explicit_temporary_obj
{
364 Ref
{ *provide() }->method();
365 RefPtr
{ provide() }->method();
367 template <typename T
>
369 Ref(*provide())->method();
370 RefPtr(provide())->method();
377 namespace call_with_explicit_construct
{
380 namespace call_with_adopt_ref
{
388 // This is needed due to rdar://141692212.
394 adoptRef(new Obj
)->method();