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