brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.5 KiB · 27db92b Raw
517 lines · cpp
1// RUN: %check_clang_tidy %s readability-suspicious-call-argument %t -- -- -std=c++112 3void foo_1(int aaaaaa, int bbbbbb) {}4 5void foo_2(int source, int aaaaaa) {}6 7void foo_3(int valToRet, int aaaaaa) {}8 9void foo_4(int pointer, int aaaaaa) {}10 11void foo_5(int aaaaaa, int bbbbbb, int cccccc, ...) {}12 13void foo_6(const int dddddd, bool &eeeeee) {}14 15void foo_7(int aaaaaa, int bbbbbb, int cccccc, int ffffff = 7) {}16 17void foo_8(int frobble1, int frobble2) {}18 19// Test functions for convertible argument--parameter types.20void fun(const int &m);21void fun2() {22  int m = 3;23  fun(m);24}25 26// Test cases for parameters of const reference and value.27void value_const_reference(int llllll, const int &kkkkkk);28 29void const_ref_value_swapped() {30  const int &kkkkkk = 42;31  const int &llllll = 42;32  value_const_reference(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 here35}36 37// Const, non const references.38void const_nonconst_parameters(const int &mmmmmm, int &nnnnnn);39 40void 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(nnnnnn, mmmmmm);45}46 47void 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(nnnnnn, mmmmmm);53}54 55void const_nonconst_swap2() {56  int nnnnnn;57  int mmmmmm;58  // Check for swapped arguments. (Both arguments are non-const.)59  const_nonconst_parameters(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 63void const_nonconst_pointers(const int *mmmmmm, int *nnnnnn);64void const_nonconst_pointers2(const int *mmmmmm, const int *nnnnnn);65 66void const_nonconst_pointers_swapped() {67  int *mmmmmm;68  const int *nnnnnn;69  const_nonconst_pointers(nnnnnn, mmmmmm);70}71 72void const_nonconst_pointers_swapped2() {73  const int *mmmmmm;74  int *nnnnnn;75  const_nonconst_pointers2(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.80void pointer_array_parameters(81    int *pppppp, int qqqqqq[4]);82 83void 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(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.92void multilevel_pointer_parameters(int *const **pppppp,93                                   const int *const *volatile const *qqqqqq);94void multilevel_pointer_parameters2(95    char *****nnnnnn, char *volatile *const *const *const *const &mmmmmm);96 97typedef float T;98typedef T *S;99typedef S *const volatile R;100typedef R *Q;101typedef Q *P;102typedef P *O;103void multilevel_pointer_parameters3(float **const volatile ***rrrrrr, O &ssssss);104 105void multilevel_pointer_swap() {106  int *const **qqqqqq;107  int *const **pppppp;108  multilevel_pointer_parameters(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(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(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 122void multilevel_pointer_parameters4(char ****pppppp,123                                    char *const volatile **const *qqqqqq);124void multilevel_pointer_parameters5(125    bool *****nnnnnn, bool *volatile *const *const *const *&mmmmmm);126void multilevel_pointer_parameters6(double **llllll, char **&kkkkkk);127void multilevel_pointer_parameters7(const volatile int ***iiiiii,128                                    const int *const *const *jjjjjj);129 130void multilevel_pointer_swap3() {131  char ****qqqqqq;132  char *const volatile **const *pppppp;133  // Do not check.134  multilevel_pointer_parameters4(qqqqqq, pppppp);135 136  bool *****mmmmmm;137  bool *volatile *const *const *const *nnnnnn;138  // Do not check.139  multilevel_pointer_parameters5(mmmmmm, nnnnnn);140 141  double **kkkkkk;142  char **llllll;143  multilevel_pointer_parameters6(kkkkkk, llllll);144 145  const volatile int ***jjjjjj;146  const int *const *const *iiiiii;147  multilevel_pointer_parameters7(jjjjjj, iiiiii);148}149 150// Test cases for multidimesional arrays.151void multilevel_array_parameters(int pppppp[2][2][2], const int qqqqqq[][2][2]);152 153void multilevel_array_parameters2(int (*mmmmmm)[2][2], int nnnnnn[9][2][23]);154 155void multilevel_array_parameters3(int (*eeeeee)[2][2], int (&ffffff)[1][2][2]);156 157void multilevel_array_parameters4(int (*llllll)[2][2], int kkkkkk[2][2]);158 159void multilevel_array_parameters5(int iiiiii[2][2], char jjjjjj[2][2]);160 161void multilevel_array_parameters6(int (*bbbbbb)[2][2], int cccccc[1][2][2]);162 163void 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(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(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(ffffff, eeeeee);178 179  int kkkkkk[2][2][2];180  int(*llllll)[2];181  // Do not check, argument dimensions differ.182  multilevel_array_parameters4(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(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(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 196void 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(qqqqqq, pppppp);201}202 203// Complex test case.204void 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 206void 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(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 215enum class numbers_scoped { one,216                            two };217 218// Test cases for arithmetic types.219void arithmetic_type_parameters(float vvvvvv, int wwwwww);220void arithmetic_type_parameters2(numbers_scoped vvvvvv, int wwwwww);221 222void arithmetic_types_swap1() {223  bool wwwwww;224  float vvvvvv;225  arithmetic_type_parameters(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 229void arithmetic_types_swap3() {230  char wwwwww;231  unsigned long long int vvvvvv;232  arithmetic_type_parameters(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 236void arithmetic_types_swap4() {237  enum numbers { one,238                 two };239  numbers wwwwww = numbers::one;240  int vvvvvv;241  arithmetic_type_parameters(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 245void arithmetic_types_swap5() {246  wchar_t vvvvvv;247  float wwwwww;248  arithmetic_type_parameters(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 252void 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(wwwwww, vvvvvv);257}258 259// Base, derived260class TestClass {261public:262  void thisFunction(int integerParam, int thisIsPARAM) {}263};264 265class DerivedTestClass : public TestClass {};266 267void base_derived_pointer_parameters(TestClass *aaaaaa,268                                     DerivedTestClass *bbbbbb);269 270void 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(bbbbbb, aaaaaa);275}276 277void base_derived_swap2() {278  DerivedTestClass *bbbbbb, *aaaaaa;279  // Check for swapped arguments, DerivedTestClass converts to TestClass implicitly.280  base_derived_pointer_parameters(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 284class PrivateDerivedClass : private TestClass {};285 286void private_derived_pointer_parameters(TestClass *aaaaaa, PrivateDerivedClass *bbbbbb);287 288void private_base_swap1() {289  TestClass *bbbbbb;290  PrivateDerivedClass *aaaaaa;291  private_derived_pointer_parameters(bbbbbb, aaaaaa);292}293 294// Multilevel inheritance295class DerivedOfDerivedTestClass : public DerivedTestClass {};296 297void 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      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 swaps306void funct_ptr_params(double (*ffffff)(int, int), double (*gggggg)(int, int));307void funct_ptr_params(double (*ffffff)(int, int), int (*gggggg)(int, int));308 309double ffffff(int a, int b) { return 0; }310double gggggg(int a, int b) { return 0; }311 312void funtionc_ptr_params_swap() {313  funct_ptr_params(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 317int fffff(int a, int b) { return 0; }318 319void function_ptr_swap2() {320  // Do not check, because the function `ffffff` cannot convert to a function321  // with prototype: double(int,int).322  funct_ptr_params(gggggg, fffff);323}324 325// Paraphrased example from Z3 (src/qe/qe_arrays.cpp) which originally produced326// a false positive. Operator() calls should ignore the called object327// "argument".328struct type1;329struct type2;330struct type3;331 332struct callable1 {333  void operator()(type1 &mdl, type2 &arr_vars, type3 &fml, type2 &aux_vars) const {}334};335 336struct 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 be343    // ignored!344  }345};346 347struct binop_t {};348 349binop_t operator+(const binop_t &lhs, const binop_t &rhs) { return lhs; }350bool operator<(const binop_t &lhs, const binop_t &rhs) { return true; }351bool operator>(const binop_t &aaaaaa, const binop_t &bbbbbb) { return false; }352 353void 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<(rhs, lhs))360    return;361 362  binop_t aaaaaa, cccccc;363  if (operator>(cccccc, aaaaaa))364    return;365}366 367int recursion(int aaaa, int bbbb) {368  if (aaaa)369    return 0;370 371  int cccc = 0;372  return recursion(bbbb, cccc);373  // NO-WARN: Recursive calls usually shuffle with arguments and we ignore those.374}375 376void 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.380struct value;381enum opcode { Foo,382              Bar };383static value *SimplifyRightShift(384    opcode Opcode, value *Op0, value *Op1, bool isExact,385    const type1 &Q, unsigned MaxRecurse) { return nullptr; }386static value *SimplifyLShrInst(value *Op0, value *Op1, bool isExact,387                               const type1 &Q, unsigned MaxRecurse) {388  if (value *V = SimplifyRightShift(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 395void has_unnamed(int aaaaaa, int) {}396 397int main() {398  // Equality test.399  int aaaaaa, cccccc = 0;400  foo_1(cccccc, 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(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(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(cccccc, 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(cccccc, 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(cccccc, 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(cccccc, 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(cccccc, 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(cccccc, 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(src, bbbbbb, cccccc, aaaaaa); // Should pass.445  foo_5(cccccc, bbbbbb, 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(src, bbbbbb, cccccc, 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(cccccc, bbbbbb, aaaaaa, 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(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(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(bar2, bar1); // NO-WARN.464 465  // Type match466  bool dddddd = false;467  int eeeeee = 0;468  auto szam = 0;469  foo_6(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(szam, 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(integ, thisIsAnArg); // Should pass.483 484  has_unnamed(1, bbbbbb);485 486  return 0;487}488 489namespace Issue_54074 {490 491class T {};492using OperatorTy = int(const T &, const T &);493int operator-(const T &, const T &);494 495template <typename U>496struct Wrap {497  Wrap(U);498};499 500template <typename V>501void wrapTaker(V, Wrap<OperatorTy>);502 503template <typename V>504void wrapTaker(V aaaaa, V bbbbb, Wrap<OperatorTy>);505 506void test() {507  wrapTaker(0, operator-);508  // NO-WARN. No crash!509 510  int aaaaa = 4, bbbbb = 8;511  wrapTaker(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 here514}515 516} // namespace Issue_54074517