[C++20] [Modules] Fix may-be incorrect ADL for module local entities (#123931)
[llvm-project.git] / clang / test / Analysis / Checkers / WebKit / call-args.cpp
blobb4613d5090f299112ad4abb0f73a7d0dc9d0585a
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*);
7 void some_function();
9 namespace simple {
10 void foo() {
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() {
17 [[clang::suppress]]
18 consume_refcntbl(provide()); // no-warning
22 namespace 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}}
30 namespace ref_counted {
31 Ref<RefCountable> provide_ref_counted() { return Ref<RefCountable>{}; }
32 void consume_ref_counted(Ref<RefCountable>) {}
34 void foo() {
35 consume_refcntbl(provide_ref_counted().ptr());
36 // no warning
40 namespace methods {
41 struct Consumer {
42 void consume_ptr(RefCountable* ptr);
43 void consume_ref(const RefCountable& ref);
46 void foo() {
47 Consumer c;
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}}
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}}
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}}
76 namespace casts {
77 RefCountable* downcast(RefCountable*);
79 void foo() {
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}}
98 consume_refcntbl(
99 static_cast<RefCountable*>(
100 downcast(
101 static_cast<RefCountable*>(
102 provide()
107 // expected-warning@-8{{Call argument is uncounted and unsafe}}
111 namespace null_ptr {
112 void foo_ref() {
113 consume_refcntbl(nullptr);
114 consume_refcntbl(0);
118 namespace ref_counted_lookalike {
119 struct Decoy {
120 RefCountable* get();
123 void foo() {
124 Decoy D;
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 {
133 Ref() = default;
134 Ref(T*) { }
135 T* get() { return nullptr; }
136 operator T& () { return t; }
137 T t;
140 void consume_ref(RefCountable&) {}
142 void foo() {
143 Ref<RefCountable> bar;
144 consume_ref(bar);
148 namespace param_formarding_function {
149 void consume_ref_countable_ref(RefCountable&);
150 void consume_ref_countable_ptr(RefCountable*);
152 namespace ptr {
153 void foo(RefCountable* param) {
154 consume_ref_countable_ptr(param);
158 namespace ref {
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(&param);
169 void foo_ptr(RefCountable* param) {
170 consume_ref_countable_ref(*param);
174 namespace casts {
176 RefCountable* downcast(RefCountable*) { return nullptr; }
178 template<class T>
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(); };
192 namespace ptr {
193 void foo(RefCountable* param) {
194 consume_ref_countable_ptr(param);
198 namespace ref {
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(&param);
209 void foo_ptr(RefCountable* param) {
210 consume_ref_countable_ref(*param);
214 namespace casts {
216 RefCountable* downcast(RefCountable*) { return nullptr; }
218 template<class T>
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 {
229 struct methodclass {
230 void consume_ref_countable_ref(RefCountable&) {};
231 static void consume_ref_countable_ptr(RefCountable*) {};
234 namespace ptr {
235 void foo(RefCountable* param) {
236 methodclass::consume_ref_countable_ptr(param);
240 namespace ref {
241 void foo(RefCountable& param) {
242 methodclass mc;
243 mc.consume_ref_countable_ref(param);
247 namespace ref_deref_operators {
248 void foo_ref(RefCountable& param) {
249 methodclass::consume_ref_countable_ptr(&param);
252 void foo_ptr(RefCountable* param) {
253 methodclass mc;
254 mc.consume_ref_countable_ref(*param);
258 namespace casts {
260 RefCountable* downcast(RefCountable*) { return nullptr; }
262 template<class T>
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));
272 namespace downcast {
273 void consume_ref_countable(RefCountable*) {}
274 RefCountable* downcast(RefCountable*) { return nullptr; }
276 void foo() {
277 RefPtr<RefCountable> bar;
278 consume_ref_countable( downcast(bar.get()) );
282 namespace string_impl {
283 struct String {
284 RefCountable* impl() { return nullptr; }
287 struct AtomString {
288 RefCountable rc;
289 RefCountable& impl() { return rc; }
292 void consume_ptr(RefCountable*) {}
293 void consume_ref(RefCountable&) {}
295 namespace simple {
296 void foo() {
297 String s;
298 AtomString as;
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}}
311 void foo() {
312 function_with_default_arg();
316 namespace 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();
327 namespace 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);
335 RefCountable* global;
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}}
348 namespace 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}}
362 namespace call_with_explicit_temporary_obj {
363 void foo() {
364 Ref { *provide() }->method();
365 RefPtr { provide() }->method();
367 template <typename T>
368 void bar() {
369 Ref(*provide())->method();
370 RefPtr(provide())->method();
372 void baz() {
373 bar<int>();
377 namespace call_with_explicit_construct {
380 namespace call_with_adopt_ref {
381 class Obj {
382 public:
383 void ref() const;
384 void deref() const;
385 void method();
388 // This is needed due to rdar://141692212.
389 struct dummy {
390 RefPtr<Obj> any;
393 void foo() {
394 adoptRef(new Obj)->method();