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.NamePrefixSuffixSilenceDissimilarityTreshold: 0 \
10// RUN: }}' --
11
12namespace std {
13template <typename T>
14T max(const T &A, const T &B);
15} // namespace std
16
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 the
135 // 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(X: A);
155 forwardDeclared(X: 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(X: A);
162 forwardDeclared(X: 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

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/easily-swappable-parameters-relatedness.cpp