1 | // RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++11 |
2 | |
3 | void foo_1(int aaaaaa, int bbbbbb) {} |
4 | |
5 | void foo_2(int source, int aaaaaa) {} |
6 | |
7 | void foo_3(int valToRet, int aaaaaa) {} |
8 | |
9 | void foo_4(int pointer, int aaaaaa) {} |
10 | |
11 | void foo_5(int aaaaaa, int bbbbbb, int cccccc, ...) {} |
12 | |
13 | void foo_6(const int dddddd, bool &eeeeee) {} |
14 | |
15 | void foo_7(int aaaaaa, int bbbbbb, int cccccc, int ffffff = 7) {} |
16 | |
17 | void foo_8(int frobble1, int frobble2) {} |
18 | |
19 | // Test functions for convertible argument--parameter types. |
20 | void fun(const int &m); |
21 | void fun2() { |
22 | int m = 3; |
23 | fun(m); |
24 | } |
25 | |
26 | // Test cases for parameters of const reference and value. |
27 | void value_const_reference(int llllll, const int &kkkkkk); |
28 | |
29 | void const_ref_value_swapped() { |
30 | const int &kkkkkk = 42; |
31 | const int &llllll = 42; |
32 | value_const_reference(llllll: kkkkkk, kkkkkk: llllll); |
33 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'kkkkkk' (passed to 'llllll') looks like it might be swapped with the 2nd, 'llllll' (passed to 'kkkkkk') [readability-suspicious-call-argument] |
34 | // CHECK-MESSAGES: :[[@LINE-7]]:6: note: in the call to 'value_const_reference', declared here |
35 | } |
36 | |
37 | // Const, non const references. |
38 | void const_nonconst_parameters(const int &mmmmmm, int &nnnnnn); |
39 | |
40 | void const_nonconst_swap1() { |
41 | const int &nnnnnn = 42; |
42 | int mmmmmm; |
43 | // Do not check, because non-const reference parameter cannot bind to const reference argument. |
44 | const_nonconst_parameters(mmmmmm: nnnnnn, nnnnnn&: mmmmmm); |
45 | } |
46 | |
47 | void const_nonconst_swap3() { |
48 | const int nnnnnn = 42; |
49 | int m = 42; |
50 | int &mmmmmm = m; |
51 | // Do not check, const int does not bind to non const reference. |
52 | const_nonconst_parameters(mmmmmm: nnnnnn, nnnnnn&: mmmmmm); |
53 | } |
54 | |
55 | void const_nonconst_swap2() { |
56 | int nnnnnn; |
57 | int mmmmmm; |
58 | // Check for swapped arguments. (Both arguments are non-const.) |
59 | const_nonconst_parameters(mmmmmm: nnnnnn, nnnnnn&: mmmmmm); |
60 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nnnnnn' (passed to 'mmmmmm') looks like it might be swapped with the 2nd, 'mmmmmm' (passed to 'nnnnnn') |
61 | } |
62 | |
63 | void const_nonconst_pointers(const int *mmmmmm, int *nnnnnn); |
64 | void const_nonconst_pointers2(const int *mmmmmm, const int *nnnnnn); |
65 | |
66 | void const_nonconst_pointers_swapped() { |
67 | int *mmmmmm; |
68 | const int *nnnnnn; |
69 | const_nonconst_pointers(mmmmmm: nnnnnn, nnnnnn: mmmmmm); |
70 | } |
71 | |
72 | void const_nonconst_pointers_swapped2() { |
73 | const int *mmmmmm; |
74 | int *nnnnnn; |
75 | const_nonconst_pointers2(mmmmmm: nnnnnn, nnnnnn: mmmmmm); |
76 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'nnnnnn' (passed to 'mmmmmm') looks like it might be swapped with the 2nd, 'mmmmmm' (passed to 'nnnnnn') |
77 | } |
78 | |
79 | // Test cases for pointers and arrays. |
80 | void pointer_array_parameters( |
81 | int *pppppp, int qqqqqq[4]); |
82 | |
83 | void pointer_array_swap() { |
84 | int qqqqqq[5]; |
85 | int *pppppp; |
86 | // Check for swapped arguments. An array implicitly converts to a pointer. |
87 | pointer_array_parameters(pppppp: qqqqqq, qqqqqq: pppppp); |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qqqqqq' (passed to 'pppppp') looks like it might be swapped with the 2nd, 'pppppp' (passed to 'qqqqqq') |
89 | } |
90 | |
91 | // Test cases for multilevel pointers. |
92 | void multilevel_pointer_parameters(int *const **pppppp, |
93 | const int *const *volatile const *qqqqqq); |
94 | void multilevel_pointer_parameters2( |
95 | char *****nnnnnn, char *volatile *const *const *const *const &mmmmmm); |
96 | |
97 | typedef float T; |
98 | typedef T *S; |
99 | typedef S *const volatile R; |
100 | typedef R *Q; |
101 | typedef Q *P; |
102 | typedef P *O; |
103 | void multilevel_pointer_parameters3(float **const volatile ***rrrrrr, O &ssssss); |
104 | |
105 | void multilevel_pointer_swap() { |
106 | int *const **qqqqqq; |
107 | int *const **pppppp; |
108 | multilevel_pointer_parameters(pppppp: qqqqqq, qqqqqq: pppppp); |
109 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qqqqqq' (passed to 'pppppp') looks like it might be swapped with the 2nd, 'pppppp' (passed to 'qqqqqq') |
110 | |
111 | char *****mmmmmm; |
112 | char *****nnnnnn; |
113 | multilevel_pointer_parameters2(nnnnnn: mmmmmm, mmmmmm: nnnnnn); |
114 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'mmmmmm' (passed to 'nnnnnn') looks like it might be swapped with the 2nd, 'nnnnnn' (passed to 'mmmmmm') |
115 | |
116 | float **const volatile ***rrrrrr; |
117 | float **const volatile ***ssssss; |
118 | multilevel_pointer_parameters3(rrrrrr: ssssss, ssssss&: rrrrrr); |
119 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'ssssss' (passed to 'rrrrrr') looks like it might be swapped with the 2nd, 'rrrrrr' (passed to 'ssssss') |
120 | } |
121 | |
122 | void multilevel_pointer_parameters4(char ****pppppp, |
123 | char *const volatile **const *qqqqqq); |
124 | void multilevel_pointer_parameters5( |
125 | bool *****nnnnnn, bool *volatile *const *const *const *&mmmmmm); |
126 | void multilevel_pointer_parameters6(double **llllll, char **&kkkkkk); |
127 | void multilevel_pointer_parameters7(const volatile int ***iiiiii, |
128 | const int *const *const *jjjjjj); |
129 | |
130 | void multilevel_pointer_swap3() { |
131 | char ****qqqqqq; |
132 | char *const volatile **const *pppppp; |
133 | // Do not check. |
134 | multilevel_pointer_parameters4(pppppp: qqqqqq, qqqqqq: pppppp); |
135 | |
136 | bool *****mmmmmm; |
137 | bool *volatile *const *const *const *nnnnnn; |
138 | // Do not check. |
139 | multilevel_pointer_parameters5(nnnnnn: mmmmmm, mmmmmm&: nnnnnn); |
140 | |
141 | double **kkkkkk; |
142 | char **llllll; |
143 | multilevel_pointer_parameters6(llllll: kkkkkk, kkkkkk&: llllll); |
144 | |
145 | const volatile int ***jjjjjj; |
146 | const int *const *const *iiiiii; |
147 | multilevel_pointer_parameters7(iiiiii: jjjjjj, jjjjjj: iiiiii); |
148 | } |
149 | |
150 | // Test cases for multidimesional arrays. |
151 | void multilevel_array_parameters(int pppppp[2][2][2], const int qqqqqq[][2][2]); |
152 | |
153 | void multilevel_array_parameters2(int (*mmmmmm)[2][2], int nnnnnn[9][2][23]); |
154 | |
155 | void multilevel_array_parameters3(int (*eeeeee)[2][2], int (&ffffff)[1][2][2]); |
156 | |
157 | void multilevel_array_parameters4(int (*llllll)[2][2], int kkkkkk[2][2]); |
158 | |
159 | void multilevel_array_parameters5(int iiiiii[2][2], char jjjjjj[2][2]); |
160 | |
161 | void multilevel_array_parameters6(int (*bbbbbb)[2][2], int cccccc[1][2][2]); |
162 | |
163 | void multilevel_array_swap() { |
164 | int qqqqqq[1][2][2]; |
165 | int pppppp[][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}}; // int [2][2][2] |
166 | multilevel_array_parameters(pppppp: qqqqqq, qqqqqq: pppppp); |
167 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'qqqqqq' (passed to 'pppppp') looks like it might be swapped with the 2nd, 'pppppp' (passed to 'qqqqqq') |
168 | |
169 | int(*nnnnnn)[2][2]; |
170 | int mmmmmm[9][2][23]; |
171 | // Do not check, array sizes has to match in every dimension, except the first. |
172 | multilevel_array_parameters2(mmmmmm: nnnnnn, nnnnnn: mmmmmm); |
173 | |
174 | int ffffff[][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}}; // int [2][2][2] |
175 | int eeeeee[1][2][2] = {{{1, 2}, {1, 2}}}; // int [1][2][2] |
176 | // Do not check, for array references, size has to match in every dimension. |
177 | multilevel_array_parameters3(eeeeee: ffffff, ffffff&: eeeeee); |
178 | |
179 | int kkkkkk[2][2][2]; |
180 | int(*llllll)[2]; |
181 | // Do not check, argument dimensions differ. |
182 | multilevel_array_parameters4(llllll: kkkkkk, kkkkkk: llllll); |
183 | |
184 | int jjjjjj[2][2]; |
185 | char iiiiii[2][2]; |
186 | // Do not check, array element types differ. |
187 | multilevel_array_parameters5(iiiiii: jjjjjj, jjjjjj: iiiiii); |
188 | |
189 | int t[][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}}; // int [2][2][2] |
190 | int(*cccccc)[2][2] = t; // int (*)[2][2] |
191 | int bbbbbb[][2][2] = {{{1, 2}, {1, 2}}}; // int [1][2][2] |
192 | multilevel_array_parameters6(bbbbbb: cccccc, cccccc: bbbbbb); |
193 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'bbbbbb') looks like it might be swapped with the 2nd, 'bbbbbb' (passed to 'cccccc') |
194 | } |
195 | |
196 | void multilevel_array_swap2() { |
197 | int qqqqqq[2][2][2]; |
198 | const int pppppp[][2][2] = {{{1, 2}, {1, 2}}, {{1, 2}, {1, 2}}}; |
199 | // Do not check, pppppp is const and cannot bind to an array with nonconst elements. |
200 | multilevel_array_parameters(pppppp: qqqqqq, qqqqqq: pppppp); |
201 | } |
202 | |
203 | // Complex test case. |
204 | void multilevel_pointer_array_parameters(const int(*const (*volatile const (*const (*const (*const &aaaaaa)[1])[32])[4])[3][2][2]), const int(*const (*volatile const (*const (*const (*&bbbbbb)[1])[32])[4])[3][2][2])); |
205 | |
206 | void multilevel_pointer_array_swap() { |
207 | const int( |
208 | *const(*volatile const(*const(*const(*aaaaaa)[1])[32])[4])[3][2][2]); |
209 | const int( |
210 | *const(*volatile const(*const(*const(*bbbbbb)[1])[32])[4])[3][2][2]); |
211 | multilevel_pointer_array_parameters(aaaaaa: bbbbbb, bbbbbb&: aaaaaa); |
212 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'bbbbbb' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaaaa' (passed to 'bbbbbb') |
213 | } |
214 | |
215 | enum class numbers_scoped { one, |
216 | two }; |
217 | |
218 | // Test cases for arithmetic types. |
219 | void arithmetic_type_parameters(float vvvvvv, int wwwwww); |
220 | void arithmetic_type_parameters2(numbers_scoped vvvvvv, int wwwwww); |
221 | |
222 | void arithmetic_types_swap1() { |
223 | bool wwwwww; |
224 | float vvvvvv; |
225 | arithmetic_type_parameters(vvvvvv: wwwwww, wwwwww: vvvvvv); |
226 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'wwwwww' (passed to 'vvvvvv') looks like it might be swapped with the 2nd, 'vvvvvv' (passed to 'wwwwww') |
227 | } |
228 | |
229 | void arithmetic_types_swap3() { |
230 | char wwwwww; |
231 | unsigned long long int vvvvvv; |
232 | arithmetic_type_parameters(vvvvvv: wwwwww, wwwwww: vvvvvv); |
233 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'wwwwww' (passed to 'vvvvvv') looks like it might be swapped with the 2nd, 'vvvvvv' (passed to 'wwwwww') |
234 | } |
235 | |
236 | void arithmetic_types_swap4() { |
237 | enum numbers { one, |
238 | two }; |
239 | numbers wwwwww = numbers::one; |
240 | int vvvvvv; |
241 | arithmetic_type_parameters(vvvvvv: wwwwww, wwwwww: vvvvvv); |
242 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'wwwwww' (passed to 'vvvvvv') looks like it might be swapped with the 2nd, 'vvvvvv' (passed to 'wwwwww') |
243 | } |
244 | |
245 | void arithmetic_types_swap5() { |
246 | wchar_t vvvvvv; |
247 | float wwwwww; |
248 | arithmetic_type_parameters(vvvvvv: wwwwww, wwwwww: vvvvvv); |
249 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'wwwwww' (passed to 'vvvvvv') looks like it might be swapped with the 2nd, 'vvvvvv' (passed to 'wwwwww') |
250 | } |
251 | |
252 | void arithmetic_types_swap6() { |
253 | wchar_t vvvvvv; |
254 | numbers_scoped wwwwww = numbers_scoped::one; |
255 | // Do not check, numers is a scoped enum type. |
256 | arithmetic_type_parameters2(vvvvvv: wwwwww, wwwwww: vvvvvv); |
257 | } |
258 | |
259 | // Base, derived |
260 | class TestClass { |
261 | public: |
262 | void thisFunction(int integerParam, int thisIsPARAM) {} |
263 | }; |
264 | |
265 | class DerivedTestClass : public TestClass {}; |
266 | |
267 | void base_derived_pointer_parameters(TestClass *aaaaaa, |
268 | DerivedTestClass *bbbbbb); |
269 | |
270 | void base_derived_swap1() { |
271 | TestClass *bbbbbb; |
272 | DerivedTestClass *aaaaaa; |
273 | // Do not check, because TestClass does not convert implicitly to DerivedTestClass. |
274 | base_derived_pointer_parameters(aaaaaa: bbbbbb, bbbbbb: aaaaaa); |
275 | } |
276 | |
277 | void base_derived_swap2() { |
278 | DerivedTestClass *bbbbbb, *aaaaaa; |
279 | // Check for swapped arguments, DerivedTestClass converts to TestClass implicitly. |
280 | base_derived_pointer_parameters(aaaaaa: bbbbbb, bbbbbb: aaaaaa); |
281 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'bbbbbb' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaaaa' (passed to 'bbbbbb') |
282 | } |
283 | |
284 | class PrivateDerivedClass : private TestClass {}; |
285 | |
286 | void private_derived_pointer_parameters(TestClass *aaaaaa, PrivateDerivedClass *bbbbbb); |
287 | |
288 | void private_base_swap1() { |
289 | TestClass *bbbbbb; |
290 | PrivateDerivedClass *aaaaaa; |
291 | private_derived_pointer_parameters(aaaaaa: bbbbbb, bbbbbb: aaaaaa); |
292 | } |
293 | |
294 | // Multilevel inheritance |
295 | class DerivedOfDerivedTestClass : public DerivedTestClass {}; |
296 | |
297 | void multi_level_inheritance_swap() { |
298 | DerivedOfDerivedTestClass *aaaaaa, *bbbbbb; |
299 | // Check for swapped arguments. Derived classes implicitly convert to their base. |
300 | base_derived_pointer_parameters( |
301 | aaaaaa: bbbbbb, bbbbbb: aaaaaa); |
302 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: 1st argument 'bbbbbb' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaaaa' (passed to 'bbbbbb') |
303 | } |
304 | |
305 | // Tests for function pointer swaps |
306 | void funct_ptr_params(double (*ffffff)(int, int), double (*gggggg)(int, int)); |
307 | void funct_ptr_params(double (*ffffff)(int, int), int (*gggggg)(int, int)); |
308 | |
309 | double ffffff(int a, int b) { return 0; } |
310 | double gggggg(int a, int b) { return 0; } |
311 | |
312 | void funtionc_ptr_params_swap() { |
313 | funct_ptr_params(ffffff: gggggg, gggggg: ffffff); |
314 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'gggggg' (passed to 'ffffff') looks like it might be swapped with the 2nd, 'ffffff' (passed to 'gggggg') |
315 | } |
316 | |
317 | int fffff(int a, int b) { return 0; } |
318 | |
319 | void function_ptr_swap2() { |
320 | // Do not check, because the function `ffffff` cannot convert to a function |
321 | // with prototype: double(int,int). |
322 | funct_ptr_params(ffffff: gggggg, gggggg: fffff); |
323 | } |
324 | |
325 | // Paraphrased example from Z3 (src/qe/qe_arrays.cpp) which originally produced |
326 | // a false positive. Operator() calls should ignore the called object |
327 | // "argument". |
328 | struct type1; |
329 | struct type2; |
330 | struct type3; |
331 | |
332 | struct callable1 { |
333 | void operator()(type1 &mdl, type2 &arr_vars, type3 &fml, type2 &aux_vars) const {} |
334 | }; |
335 | |
336 | struct callable2 { |
337 | void operator()(type1 &mdl, type2 &arr_vars, type3 &fml, type2 &aux_vars, |
338 | bool reduce_all_selects) const { |
339 | (void)reduce_all_selects; |
340 | callable1 pe; |
341 | pe(mdl, arr_vars, fml, aux_vars); |
342 | // NO-WARN: Argument and parameter names match perfectly, "pe" should be |
343 | // ignored! |
344 | } |
345 | }; |
346 | |
347 | struct binop_t {}; |
348 | |
349 | binop_t operator+(const binop_t &lhs, const binop_t &rhs) { return lhs; } |
350 | bool operator<(const binop_t &lhs, const binop_t &rhs) { return true; } |
351 | bool operator>(const binop_t &aaaaaa, const binop_t &bbbbbb) { return false; } |
352 | |
353 | void binop_test() { |
354 | // NO-WARN: Binary operators are ignored. |
355 | binop_t lhs, rhs; |
356 | if (lhs + rhs < rhs) |
357 | return; |
358 | |
359 | if (operator<(lhs: rhs, rhs: lhs)) |
360 | return; |
361 | |
362 | binop_t aaaaaa, cccccc; |
363 | if (operator>(aaaaaa: cccccc, bbbbbb: aaaaaa)) |
364 | return; |
365 | } |
366 | |
367 | int recursion(int aaaa, int bbbb) { |
368 | if (aaaa) |
369 | return 0; |
370 | |
371 | int cccc = 0; |
372 | return recursion(aaaa: bbbb, bbbb: cccc); |
373 | // NO-WARN: Recursive calls usually shuffle with arguments and we ignore those. |
374 | } |
375 | |
376 | void pass_by_copy(binop_t xxxx, binop_t yyyy) {} |
377 | |
378 | // Paraphrased example from LLVM's code (lib/Analysis/InstructionSimplify.cpp) |
379 | // that generated a false positive. |
380 | struct value; |
381 | enum opcode { Foo, |
382 | Bar }; |
383 | static value *SimplifyRightShift( |
384 | opcode Opcode, value *Op0, value *Op1, bool isExact, |
385 | const type1 &Q, unsigned MaxRecurse) {} |
386 | static value *SimplifyLShrInst(value *Op0, value *Op1, bool isExact, |
387 | const type1 &Q, unsigned MaxRecurse) { |
388 | if (value *V = SimplifyRightShift(Opcode: Foo, Op0, Op1, isExact, Q, MaxRecurse)) |
389 | return V; |
390 | // NO-WARN: Argument names perfectly match parameter names, sans the enum. |
391 | |
392 | return nullptr; |
393 | } |
394 | |
395 | void has_unnamed(int aaaaaa, int) {} |
396 | |
397 | int main() { |
398 | // Equality test. |
399 | int aaaaaa, cccccc = 0; |
400 | foo_1(aaaaaa: cccccc, bbbbbb: aaaaaa); |
401 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaaaa' (passed to 'bbbbbb') |
402 | |
403 | binop_t xxxx, yyyy; |
404 | pass_by_copy(xxxx: yyyy, yyyy: xxxx); |
405 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'yyyy' (passed to 'xxxx') looks like it might be swapped with the 2nd, 'xxxx' (passed to 'yyyy') |
406 | |
407 | // Abbreviation test. |
408 | int src = 0; |
409 | foo_2(source: aaaaaa, aaaaaa: src); |
410 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'aaaaaa' (passed to 'source') looks like it might be swapped with the 2nd, 'src' (passed to 'aaaaaa') |
411 | |
412 | // Levenshtein test. |
413 | int aaaabb = 0; |
414 | foo_1(aaaaaa: cccccc, bbbbbb: aaaabb); |
415 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaabb' (passed to 'bbbbbb') |
416 | |
417 | // Prefix test. |
418 | int aaaa = 0; |
419 | foo_1(aaaaaa: cccccc, bbbbbb: aaaa); |
420 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaa' (passed to 'bbbbbb') |
421 | |
422 | // Suffix test. |
423 | int urce = 0; |
424 | foo_2(source: cccccc, aaaaaa: urce); |
425 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'source') looks like it might be swapped with the 2nd, 'urce' (passed to 'aaaaaa') |
426 | |
427 | // Substring test. |
428 | int ourc = 0; |
429 | foo_2(source: cccccc, aaaaaa: ourc); |
430 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'source') looks like it might be swapped with the 2nd, 'ourc' (passed to 'aaaaaa') |
431 | |
432 | // Jaro-Winkler test. |
433 | int iPonter = 0; |
434 | foo_4(pointer: cccccc, aaaaaa: iPonter); |
435 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'pointer') looks like it might be swapped with the 2nd, 'iPonter' (passed to 'aaaaaa') |
436 | |
437 | // Dice test. |
438 | int aaabaa = 0; |
439 | foo_1(aaaaaa: cccccc, bbbbbb: aaabaa); |
440 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaabaa' (passed to 'bbbbbb') |
441 | |
442 | // Variadic function test. |
443 | int bbbbbb = 0; |
444 | foo_5(aaaaaa: src, bbbbbb, cccccc, aaaaaa); // Should pass. |
445 | foo_5(aaaaaa: cccccc, bbbbbb, cccccc: aaaaaa, src); |
446 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 3rd, 'aaaaaa' (passed to 'cccccc') |
447 | |
448 | // Test function with default argument. |
449 | foo_7(aaaaaa: src, bbbbbb, cccccc, ffffff: aaaaaa); |
450 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'src' (passed to 'aaaaaa') looks like it might be swapped with the 4th, 'aaaaaa' (passed to 'ffffff') |
451 | |
452 | foo_7(aaaaaa: cccccc, bbbbbb, cccccc: aaaaaa, ffffff: src); |
453 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'cccccc' (passed to 'aaaaaa') looks like it might be swapped with the 3rd, 'aaaaaa' (passed to 'cccccc') |
454 | |
455 | int ffffff = 0; |
456 | foo_7(aaaaaa: ffffff, bbbbbb, cccccc); // NO-WARN: Even though 'ffffff' is passed to 'aaaaaa' and there is a 4th parameter 'ffffff', there isn't a **swap** here. |
457 | |
458 | int frobble1 = 1, frobble2 = 2; |
459 | foo_8(frobble1: frobble2, frobble2: frobble1); |
460 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'frobble2' (passed to 'frobble1') looks like it might be swapped with the 2nd, 'frobble1' (passed to 'frobble2') |
461 | |
462 | int bar1 = 1, bar2 = 2; |
463 | foo_8(frobble1: bar2, frobble2: bar1); // NO-WARN. |
464 | |
465 | // Type match |
466 | bool dddddd = false; |
467 | int eeeeee = 0; |
468 | auto szam = 0; |
469 | foo_6(dddddd: eeeeee, eeeeee&: dddddd); |
470 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'eeeeee' (passed to 'dddddd') looks like it might be swapped with the 2nd, 'dddddd' (passed to 'eeeeee') |
471 | foo_1(aaaaaa: szam, bbbbbb: aaaaaa); |
472 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'szam' (passed to 'aaaaaa') looks like it might be swapped with the 2nd, 'aaaaaa' (passed to 'bbbbbb') |
473 | |
474 | // Test lambda. |
475 | auto testMethod = [&](int method, int randomParam) { return 0; }; |
476 | int method = 0; |
477 | testMethod(method, 0); // Should pass. |
478 | |
479 | // Member function test. |
480 | TestClass test; |
481 | int integ, thisIsAnArg = 0; |
482 | test.thisFunction(integerParam: integ, thisIsPARAM: thisIsAnArg); // Should pass. |
483 | |
484 | has_unnamed(aaaaaa: 1, bbbbbb); |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | namespace Issue_54074 { |
490 | |
491 | class T {}; |
492 | using OperatorTy = int(const T &, const T &); |
493 | int operator-(const T &, const T &); |
494 | |
495 | template <typename U> |
496 | struct Wrap { |
497 | Wrap(U); |
498 | }; |
499 | |
500 | template <typename V> |
501 | void wrapTaker(V, Wrap<OperatorTy>); |
502 | |
503 | template <typename V> |
504 | void wrapTaker(V aaaaa, V bbbbb, Wrap<OperatorTy>); |
505 | |
506 | void test() { |
507 | wrapTaker(0, operator-); |
508 | // NO-WARN. No crash! |
509 | |
510 | int aaaaa = 4, bbbbb = 8; |
511 | wrapTaker(aaaaa: bbbbb, bbbbb: aaaaa, operator-); |
512 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 1st argument 'bbbbb' (passed to 'aaaaa') looks like it might be swapped with the 2nd, 'aaaaa' (passed to 'bbbbb') |
513 | // CHECK-MESSAGES: :[[@LINE-9]]:6: note: in the call to 'wrapTaker<int>', declared here |
514 | } |
515 | |
516 | } // namespace Issue_54074 |
517 | |