233 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \2// RUN: -config='{CheckOptions: { \3// RUN: bugprone-easily-swappable-parameters.MinimumLength: 2, \4// RUN: bugprone-easily-swappable-parameters.IgnoredParameterNames: "", \5// RUN: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes: "", \6// RUN: bugprone-easily-swappable-parameters.QualifiersMix: 0, \7// RUN: bugprone-easily-swappable-parameters.ModelImplicitConversions: 0, \8// RUN: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether: 1, \9// RUN: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityThreshold: 0 \10// RUN: }}' --11 12namespace std {13template <typename T>14T max(const T &A, const T &B);15} // namespace std16 17bool coin();18void f(int);19void g(int);20void h(int, int);21void i(int, bool);22void i(int, char);23 24struct Tmp {25 int f(int);26 int g(int, int);27};28 29struct Int {30 int I;31};32 33void compare(int Left, int Right) {}34// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 2 adjacent parameters of 'compare' of similar type ('int')35// CHECK-MESSAGES: :[[@LINE-2]]:18: note: the first parameter in the range is 'Left'36// CHECK-MESSAGES: :[[@LINE-3]]:28: note: the last parameter in the range is 'Right'37 38int decideSequence(int A, int B) {39 if (A)40 return 1;41 if (B)42 return 2;43 return 3;44}45// CHECK-MESSAGES: :[[@LINE-7]]:20: warning: 2 adjacent parameters of 'decideSequence' of similar type ('int')46// CHECK-MESSAGES: :[[@LINE-8]]:24: note: the first parameter in the range is 'A'47// CHECK-MESSAGES: :[[@LINE-9]]:31: note: the last parameter in the range is 'B'48 49int myMax(int A, int B) { // NO-WARN: Appears in same expression.50 return A < B ? A : B;51}52 53int myMax2(int A, int B) { // NO-WARN: Appears in same expression.54 if (A < B)55 return A;56 return B;57}58 59int myMax3(int A, int B) { // NO-WARN: Appears in same expression.60 return std::max(A, B);61}62 63int binaryToUnary(int A, int) {64 return A;65}66// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: 2 adjacent parameters of 'binaryToUnary' of similar type ('int')67// CHECK-MESSAGES: :[[@LINE-4]]:23: note: the first parameter in the range is 'A'68// CHECK-MESSAGES: :[[@LINE-5]]:29: note: the last parameter in the range is '<unnamed>'69 70int randomReturn1(int A, int B) { // NO-WARN: Appears in same expression.71 return coin() ? A : B;72}73 74int randomReturn2(int A, int B) { // NO-WARN: Both parameters returned.75 if (coin())76 return A;77 return B;78}79 80int randomReturn3(int A, int B) { // NO-WARN: Both parameters returned.81 bool Flip = coin();82 if (Flip)83 return A;84 Flip = coin();85 if (Flip)86 return B;87 Flip = coin();88 if (!Flip)89 return 0;90 return -1;91}92 93void passthrough1(int A, int B) { // WARN: Different functions, different params.94 f(A);95 g(B);96}97// CHECK-MESSAGES: :[[@LINE-4]]:19: warning: 2 adjacent parameters of 'passthrough1' of similar type ('int')98// CHECK-MESSAGES: :[[@LINE-5]]:23: note: the first parameter in the range is 'A'99// CHECK-MESSAGES: :[[@LINE-6]]:30: note: the last parameter in the range is 'B'100 101void passthrough2(int A, int B) { // NO-WARN: Passed to same index of same function.102 f(A);103 f(B);104}105 106void passthrough3(int A, int B) { // NO-WARN: Passed to same index of same funtion.107 h(1, A);108 h(1, B);109}110 111void passthrough4(int A, int B) { // WARN: Different index used.112 h(1, A);113 h(B, 2);114}115// CHECK-MESSAGES: :[[@LINE-4]]:19: warning: 2 adjacent parameters of 'passthrough4' of similar type ('int')116// CHECK-MESSAGES: :[[@LINE-5]]:23: note: the first parameter in the range is 'A'117// CHECK-MESSAGES: :[[@LINE-6]]:30: note: the last parameter in the range is 'B'118 119void passthrough5(int A, int B) { // WARN: Different function overload.120 i(A, false);121 i(A, '\0');122}123// CHECK-MESSAGES: :[[@LINE-4]]:19: warning: 2 adjacent parameters of 'passthrough5' of similar type ('int')124// CHECK-MESSAGES: :[[@LINE-5]]:23: note: the first parameter in the range is 'A'125// CHECK-MESSAGES: :[[@LINE-6]]:30: note: the last parameter in the range is 'B'126 127void passthrough6(int A, int B) { // NO-WARN: Passed to same index of same function.128 Tmp Temp;129 Temp.f(A);130 Temp.f(B);131}132 133void passthrough7(int A, int B) { // NO-WARN: Passed to same index of same function.134 // Clang-Tidy isn't path sensitive, the fact that the two objects we call the135 // function on is different is not modelled.136 Tmp Temp1, Temp2;137 Temp1.f(A);138 Temp2.f(B);139}140 141void passthrough8(int A, int B) { // WARN: Different functions used.142 f(A);143 Tmp{}.f(B);144}145// CHECK-MESSAGES: :[[@LINE-4]]:19: warning: 2 adjacent parameters of 'passthrough8' of similar type ('int')146// CHECK-MESSAGES: :[[@LINE-5]]:23: note: the first parameter in the range is 'A'147// CHECK-MESSAGES: :[[@LINE-6]]:30: note: the last parameter in the range is 'B'148 149// Test that the matching of "passed-to-function" is done to the proper node.150// Put simply, this test should not crash here.151void forwardDeclared(int X);152 153void passthrough9(int A, int B) { // NO-WARN: Passed to same index of same function.154 forwardDeclared(A);155 forwardDeclared(B);156}157 158void forwardDeclared(int X) {}159 160void passthrough10(int A, int B) { // NO-WARN: Passed to same index of same function.161 forwardDeclared(A);162 forwardDeclared(B);163}164 165bool compare1(Int I, Int J) { // NO-WARN: Same member accessed.166 int Val1 = I.I;167 int Val2 = J.I;168 return Val1 < Val2;169}170 171bool compare2(Tmp T1, Tmp T2) { // NO-WARN: Same member accessed.172 int Val1 = T1.g(0, 1);173 int Val2 = T2.g(2, 3);174 return Val1 < Val2;175}176 177bool compare3(Tmp T1, Tmp T2) { // WARN: Different member accessed.178 int Val1 = T1.f(0);179 int Val2 = T2.g(1, 2);180 return Val1 < Val2;181}182// CHECK-MESSAGES: :[[@LINE-5]]:15: warning: 2 adjacent parameters of 'compare3' of similar type ('Tmp')183// CHECK-MESSAGES: :[[@LINE-6]]:19: note: the first parameter in the range is 'T1'184// CHECK-MESSAGES: :[[@LINE-7]]:27: note: the last parameter in the range is 'T2'185 186int rangeBreaker(int I, int J, int K, int L, int M, int N) {187 // (I, J) swappable.188 189 if (J == K) // (J, K) related.190 return -1;191 192 if (K + 2 > Tmp{}.f(K))193 return M;194 195 // (K, L, M) swappable.196 197 return N; // (M, N) related.198}199// CHECK-MESSAGES: :[[@LINE-13]]:18: warning: 2 adjacent parameters of 'rangeBreaker' of similar type ('int')200// CHECK-MESSAGES: :[[@LINE-14]]:22: note: the first parameter in the range is 'I'201// CHECK-MESSAGES: :[[@LINE-15]]:29: note: the last parameter in the range is 'J'202// CHECK-MESSAGES: :[[@LINE-16]]:32: warning: 3 adjacent parameters of 'rangeBreaker' of similar type ('int')203// CHECK-MESSAGES: :[[@LINE-17]]:36: note: the first parameter in the range is 'K'204// CHECK-MESSAGES: :[[@LINE-18]]:50: note: the last parameter in the range is 'M'205 206int returnsNotOwnParameter(int I, int J, int K) {207 const auto &Lambda = [&K](int L, int M, int N) {208 if (K)209 return L;210 return M; // (L, M) related.211 };212 213 if (Lambda(-1, 0, 1))214 return I;215 return J; // (I, J) related.216}217// CHECK-MESSAGES: :[[@LINE-11]]:35: warning: 2 adjacent parameters of 'returnsNotOwnParameter' of similar type ('int')218// CHECK-MESSAGES: :[[@LINE-12]]:39: note: the first parameter in the range is 'J'219// CHECK-MESSAGES: :[[@LINE-13]]:46: note: the last parameter in the range is 'K'220// CHECK-MESSAGES: :[[@LINE-13]]:36: warning: 2 adjacent parameters of 'operator()' of similar type ('int')221// CHECK-MESSAGES: :[[@LINE-14]]:40: note: the first parameter in the range is 'M'222// CHECK-MESSAGES: :[[@LINE-15]]:47: note: the last parameter in the range is 'N'223 224int usedTogetherInCapture(int I, int J, int K) { // NO-WARN: Used together.225 const auto &Lambda = [I, J, K]() {226 int A = I + 1;227 int B = J - 2;228 int C = K * 3;229 return A + B + C;230 };231 return Lambda();232}233