| 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) { return nullptr; } |
| 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 | |