1 // RUN: %check_clang_tidy %s bugprone-easily-swappable-parameters %t \
2 // RUN: -config='{CheckOptions: [ \
3 // RUN: {key: bugprone-easily-swappable-parameters.MinimumLength, value: 2}, \
4 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterNames, value: ""}, \
5 // RUN: {key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes, value: ""}, \
6 // RUN: {key: bugprone-easily-swappable-parameters.QualifiersMix, value: 0}, \
7 // RUN: {key: bugprone-easily-swappable-parameters.ModelImplicitConversions, value: 0}, \
8 // RUN: {key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether, value: 1}, \
9 // RUN: {key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold, value: 0} \
10 // RUN: ]}' --
11
12 namespace std {
13 template <typename T>
14 T max(const T &A, const T &B);
15 } // namespace std
16
17 bool coin();
18 void f(int);
19 void g(int);
20 void h(int, int);
21 void i(int, bool);
22 void i(int, char);
23
24 struct Tmp {
25 int f(int);
26 int g(int, int);
27 };
28
29 struct Int {
30 int I;
31 };
32
compare(int Left,int Right)33 void 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
decideSequence(int A,int B)38 int 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
myMax(int A,int B)49 int myMax(int A, int B) { // NO-WARN: Appears in same expression.
50 return A < B ? A : B;
51 }
52
myMax2(int A,int B)53 int myMax2(int A, int B) { // NO-WARN: Appears in same expression.
54 if (A < B)
55 return A;
56 return B;
57 }
58
myMax3(int A,int B)59 int myMax3(int A, int B) { // NO-WARN: Appears in same expression.
60 return std::max(A, B);
61 }
62
binaryToUnary(int A,int)63 int 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
randomReturn1(int A,int B)70 int randomReturn1(int A, int B) { // NO-WARN: Appears in same expression.
71 return coin() ? A : B;
72 }
73
randomReturn2(int A,int B)74 int randomReturn2(int A, int B) { // NO-WARN: Both parameters returned.
75 if (coin())
76 return A;
77 return B;
78 }
79
randomReturn3(int A,int B)80 int 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
passthrough1(int A,int B)93 void 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
passthrough2(int A,int B)101 void passthrough2(int A, int B) { // NO-WARN: Passed to same index of same function.
102 f(A);
103 f(B);
104 }
105
passthrough3(int A,int B)106 void passthrough3(int A, int B) { // NO-WARN: Passed to same index of same funtion.
107 h(1, A);
108 h(1, B);
109 }
110
passthrough4(int A,int B)111 void 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
passthrough5(int A,int B)119 void 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
passthrough6(int A,int B)127 void 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
passthrough7(int A,int B)133 void 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 the
135 // function on is different is not modelled.
136 Tmp Temp1, Temp2;
137 Temp1.f(A);
138 Temp2.f(B);
139 }
140
passthrough8(int A,int B)141 void 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.
151 void forwardDeclared(int X);
152
passthrough9(int A,int B)153 void passthrough9(int A, int B) { // NO-WARN: Passed to same index of same function.
154 forwardDeclared(A);
155 forwardDeclared(B);
156 }
157
forwardDeclared(int X)158 void forwardDeclared(int X) {}
159
passthrough10(int A,int B)160 void passthrough10(int A, int B) { // NO-WARN: Passed to same index of same function.
161 forwardDeclared(A);
162 forwardDeclared(B);
163 }
164
compare1(Int I,Int J)165 bool 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
compare2(Tmp T1,Tmp T2)171 bool 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
compare3(Tmp T1,Tmp T2)177 bool 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
rangeBreaker(int I,int J,int K,int L,int M,int N)186 int 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
returnsNotOwnParameter(int I,int J,int K)206 int 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
usedTogetherInCapture(int I,int J,int K)224 int 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