Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / Checkers / WebKit / call-args.cpp
blob716219836e6b4451e284564f5f55331d870a3e9c
1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
3 #include "mock-types.h"
5 RefCountable* provide() { return nullptr; }
6 void consume_refcntbl(RefCountable*) {}
8 namespace simple {
9 void foo() {
10 consume_refcntbl(provide());
11 // expected-warning@-1{{Call argument is uncounted and unsafe}}
15 namespace multi_arg {
16 void consume_refcntbl(int, RefCountable* foo, bool) {}
17 void foo() {
18 consume_refcntbl(42, provide(), true);
19 // expected-warning@-1{{Call argument for parameter 'foo' is uncounted and unsafe}}
23 namespace ref_counted {
24 Ref<RefCountable> provide_ref_counted() { return Ref<RefCountable>{}; }
25 void consume_ref_counted(Ref<RefCountable>) {}
27 void foo() {
28 consume_refcntbl(provide_ref_counted().get());
29 // no warning
33 namespace methods {
34 struct Consumer {
35 void consume_ptr(RefCountable* ptr) {}
36 void consume_ref(const RefCountable& ref) {}
39 void foo() {
40 Consumer c;
42 c.consume_ptr(provide());
43 // expected-warning@-1{{Call argument for parameter 'ptr' is uncounted and unsafe}}
44 c.consume_ref(*provide());
45 // expected-warning@-1{{Call argument for parameter 'ref' is uncounted and unsafe}}
48 void foo2() {
49 struct Consumer {
50 void consume(RefCountable*) { }
51 void whatever() {
52 consume(provide());
53 // expected-warning@-1{{Call argument is uncounted and unsafe}}
58 void foo3() {
59 struct Consumer {
60 void consume(RefCountable*) { }
61 void whatever() {
62 this->consume(provide());
63 // expected-warning@-1{{Call argument is uncounted and unsafe}}
69 namespace casts {
70 RefCountable* downcast(RefCountable*) { return nullptr; }
72 void foo() {
73 consume_refcntbl(provide());
74 // expected-warning@-1{{Call argument is uncounted and unsafe}}
76 consume_refcntbl(static_cast<RefCountable*>(provide()));
77 // expected-warning@-1{{Call argument is uncounted and unsafe}}
79 consume_refcntbl(dynamic_cast<RefCountable*>(provide()));
80 // expected-warning@-1{{Call argument is uncounted and unsafe}}
82 consume_refcntbl(const_cast<RefCountable*>(provide()));
83 // expected-warning@-1{{Call argument is uncounted and unsafe}}
85 consume_refcntbl(reinterpret_cast<RefCountable*>(provide()));
86 // expected-warning@-1{{Call argument is uncounted and unsafe}}
88 consume_refcntbl(downcast(provide()));
89 // expected-warning@-1{{Call argument is uncounted and unsafe}}
91 consume_refcntbl(
92 static_cast<RefCountable*>(
93 downcast(
94 static_cast<RefCountable*>(
95 provide()
100 // expected-warning@-8{{Call argument is uncounted and unsafe}}
104 namespace null_ptr {
105 void foo_ref() {
106 consume_refcntbl(nullptr);
107 consume_refcntbl(0);
111 namespace ref_counted_lookalike {
112 struct Decoy {
113 RefCountable* get() { return nullptr; }
116 void foo() {
117 Decoy D;
119 consume_refcntbl(D.get());
120 // expected-warning@-1{{Call argument is uncounted and unsafe}}
124 namespace Ref_to_reference_conversion_operator {
125 template<typename T> struct Ref {
126 Ref() = default;
127 Ref(T*) { }
128 T* get() { return nullptr; }
129 operator T& () { return t; }
130 T t;
133 void consume_ref(RefCountable&) {}
135 void foo() {
136 Ref<RefCountable> bar;
137 consume_ref(bar);
141 namespace param_formarding_function {
142 void consume_ref_countable_ref(RefCountable&) {}
143 void consume_ref_countable_ptr(RefCountable*) {}
145 namespace ptr {
146 void foo(RefCountable* param) {
147 consume_ref_countable_ptr(param);
151 namespace ref {
152 void foo(RefCountable& param) {
153 consume_ref_countable_ref(param);
157 namespace ref_deref_operators {
158 void foo_ref(RefCountable& param) {
159 consume_ref_countable_ptr(&param);
162 void foo_ptr(RefCountable* param) {
163 consume_ref_countable_ref(*param);
167 namespace casts {
169 RefCountable* downcast(RefCountable*) { return nullptr; }
171 template<class T>
172 T* bitwise_cast(T*) { return nullptr; }
174 void foo(RefCountable* param) {
175 consume_ref_countable_ptr(downcast(param));
176 consume_ref_countable_ptr(bitwise_cast(param));
181 namespace param_formarding_lambda {
182 auto consume_ref_countable_ref = [](RefCountable&) {};
183 auto consume_ref_countable_ptr = [](RefCountable*) {};
185 namespace ptr {
186 void foo(RefCountable* param) {
187 consume_ref_countable_ptr(param);
191 namespace ref {
192 void foo(RefCountable& param) {
193 consume_ref_countable_ref(param);
197 namespace ref_deref_operators {
198 void foo_ref(RefCountable& param) {
199 consume_ref_countable_ptr(&param);
202 void foo_ptr(RefCountable* param) {
203 consume_ref_countable_ref(*param);
207 namespace casts {
209 RefCountable* downcast(RefCountable*) { return nullptr; }
211 template<class T>
212 T* bitwise_cast(T*) { return nullptr; }
214 void foo(RefCountable* param) {
215 consume_ref_countable_ptr(downcast(param));
216 consume_ref_countable_ptr(bitwise_cast(param));
221 namespace param_forwarding_method {
222 struct methodclass {
223 void consume_ref_countable_ref(RefCountable&) {};
224 static void consume_ref_countable_ptr(RefCountable*) {};
227 namespace ptr {
228 void foo(RefCountable* param) {
229 methodclass::consume_ref_countable_ptr(param);
233 namespace ref {
234 void foo(RefCountable& param) {
235 methodclass mc;
236 mc.consume_ref_countable_ref(param);
240 namespace ref_deref_operators {
241 void foo_ref(RefCountable& param) {
242 methodclass::consume_ref_countable_ptr(&param);
245 void foo_ptr(RefCountable* param) {
246 methodclass mc;
247 mc.consume_ref_countable_ref(*param);
251 namespace casts {
253 RefCountable* downcast(RefCountable*) { return nullptr; }
255 template<class T>
256 T* bitwise_cast(T*) { return nullptr; }
258 void foo(RefCountable* param) {
259 methodclass::consume_ref_countable_ptr(downcast(param));
260 methodclass::consume_ref_countable_ptr(bitwise_cast(param));
265 namespace downcast {
266 void consume_ref_countable(RefCountable*) {}
267 RefCountable* downcast(RefCountable*) { return nullptr; }
269 void foo() {
270 RefPtr<RefCountable> bar;
271 consume_ref_countable( downcast(bar.get()) );
275 namespace string_impl {
276 struct String {
277 RefCountable* impl() { return nullptr; }
280 struct AtomString {
281 RefCountable rc;
282 RefCountable& impl() { return rc; }
285 void consume_ptr(RefCountable*) {}
286 void consume_ref(RefCountable&) {}
288 namespace simple {
289 void foo() {
290 String s;
291 AtomString as;
292 consume_ptr(s.impl());
293 consume_ref(as.impl());
298 namespace default_arg {
299 RefCountable* global;
301 void function_with_default_arg(RefCountable* param = global) {}
302 // expected-warning@-1{{Call argument for parameter 'param' is uncounted and unsafe}}
304 void foo() {
305 function_with_default_arg();
309 namespace cxx_member_operator_call {
310 // The hidden this-pointer argument without a corresponding parameter caused couple bugs in parameter <-> argument attribution.
311 struct Foo {
312 Foo& operator+(RefCountable* bad) { return *this; }
313 friend Foo& operator-(Foo& lhs, RefCountable* bad) { return lhs; }
314 void operator()(RefCountable* bad) { }
317 RefCountable* global;
319 void foo() {
320 Foo f;
321 f + global;
322 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}
323 f - global;
324 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}
325 f(global);
326 // expected-warning@-1{{Call argument for parameter 'bad' is uncounted and unsafe}}