xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp (revision 32bcd41adcc664f6d690efc9b7cd209ac9c65f68)
1 // RUN: %check_clang_tidy -std=c++11-or-later %s readability-use-std-min-max %t -- -- -fno-delayed-template-parsing
2 #define MY_MACRO_MIN(a, b) ((a) < (b) ? (a) : (b))
3 
4 constexpr int myConstexprMin(int a, int b) {
5   return a < b ? a : b;
6 }
7 
8 constexpr int myConstexprMax(int a, int b) {
9   return a > b ? a : b;
10 }
11 
12 #define MY_IF_MACRO(condition, statement) \
13   if (condition) {                        \
14     statement                             \
15   }
16 
17 class MyClass {
18 public:
19   int member1;
20   int member2;
21 };
22 
23 template<typename T>
24 
25 void foo(T value7) {
26   int value1,value2,value3;
27 
28   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
29   // CHECK-FIXES: value1 = std::max(value1, value2);
30   if (value1 < value2)
31     value1 = value2;
32 
33   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
34   // CHECK-FIXES: value2 = std::min(value1, value2);
35   if (value1 < value2)
36     value2 = value1;
37 
38   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
39   // CHECK-FIXES: value2 = std::min(value2, value1);
40   if (value2 > value1)
41     value2 = value1;
42 
43   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
44   // CHECK-FIXES: value1 = std::max(value2, value1);
45   if (value2 > value1)
46     value1 = value2;
47 
48   // No suggestion needed here
49   if (value1 == value2)
50     value1 = value2;
51 
52   // CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
53   // CHECK-FIXES: value1 = std::max<int>(value1, value4);
54   short value4;
55   if(value1<value4)
56     value1=value4;
57 
58   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
59   // CHECK-FIXES: value3 = std::min(value1+value2, value3);
60   if(value1+value2<value3)
61     value3 = value1+value2;
62 
63   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
64   // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
65   if (value1 < myConstexprMin(value2, value3))
66     value1 = myConstexprMin(value2, value3);
67 
68   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
69   // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
70   if (value1 > myConstexprMax(value2, value3))
71     value1 = myConstexprMax(value2, value3);
72 
73   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
74   // CHECK-FIXES: value2 = std::min(value1, value2);
75   if (value1 <= value2)
76     value2 = value1;
77 
78   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
79   // CHECK-FIXES: value1 = std::max(value1, value2);
80   if (value1 <= value2)
81     value1 = value2;
82 
83   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
84   // CHECK-FIXES: value1 = std::max(value2, value1);
85   if (value2 >= value1)
86     value1 = value2;
87 
88   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
89   // CHECK-FIXES: value2 = std::min(value2, value1);
90   if (value2 >= value1)
91     value2 = value1;
92 
93   // CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
94   // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
95   MyClass obj;
96   if (obj.member1 < obj.member2)
97     obj.member1 = obj.member2;
98 
99   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
100   // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
101   if (obj.member1 < obj.member2)
102     obj.member2 = obj.member1;
103 
104   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
105   // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
106   if (obj.member2 > obj.member1)
107     obj.member2 = obj.member1;
108 
109   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
110   // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
111   if (obj.member2 > obj.member1)
112     obj.member1 = obj.member2;
113 
114   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
115   // CHECK-FIXES: obj.member1 = std::max<int>(obj.member1, value4);
116   if (obj.member1 < value4)
117     obj.member1 = value4;
118 
119   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
120   // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
121   if (obj.member1 + value2 < value3)
122     value3 = obj.member1 + value2;
123 
124   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
125   // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
126   if (value1 <= obj.member2)
127     obj.member2 = value1;
128 
129   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
130   // CHECK-FIXES: value1 = std::max(value1, obj.member2);
131   if (value1 <= obj.member2)
132     value1 = obj.member2;
133 
134   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
135   // CHECK-FIXES: value1 = std::max(obj.member2, value1);
136   if (obj.member2 >= value1)
137     value1 = obj.member2;
138 
139   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
140   // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
141   if (obj.member2 >= value1)
142     obj.member2 = value1;
143 
144   // No suggestion needed here
145   if (MY_MACRO_MIN(value1, value2) < value3)
146     value3 = MY_MACRO_MIN(value1, value2);
147 
148   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
149   // CHECK-FIXES: value4 = std::max<int>(value4, value2);
150   if (value4 < value2){
151     value4 = value2;
152   }
153 
154   // No suggestion needed here
155   if(value1 < value2)
156     value2 = value1;
157   else
158     value2 = value3;
159 
160   // No suggestion needed here
161   if(value1<value2){
162     value2 = value1;
163   }
164   else{
165     value2 = value3;
166   }
167 
168   // No suggestion needed here
169   if(value1<value2){
170     value2 = value1;
171     int res = value1 + value2;
172   }
173 
174   // No suggestion needed here
175   MY_IF_MACRO(value1 < value2, value1 = value2;)
176 
177   // No suggestion needed here
178   if(value1<value2){
179     value1 = value2;
180   }
181   else if(value1>value2){
182     value2 = value1;
183   }
184 
185   // CHECK-MESSAGES: :[[@LINE+3]]:5: warning: use `std::max` instead of `<` [readability-use-std-min-max]
186   // CHECK-FIXES: value1 = std::max(value1, value3);
187   if(value1 == value2){
188     if(value1<value3)
189       value1 = value3;
190   }
191 
192   // CHECK-MESSAGES: :[[@LINE+5]]:7: warning: use `std::max` instead of `<` [readability-use-std-min-max]
193   // CHECK-FIXES: value1 = std::max<int>(value1, value4);
194   if(value1 == value2){
195     if(value2 == value3){
196       value3+=1;
197       if(value1<value4){
198         value1 = value4;
199       }
200     }
201     else if(value3>value2){
202       value2 = value3;
203     }
204   }
205 
206   // CHECK-MESSAGES: :[[@LINE+4]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
207   // CHECK-FIXES: value6 = std::min<unsigned int>(value5, value6);
208   unsigned int value5;
209   unsigned char value6;
210   if(value5<value6){
211     value6 = value5;
212   }
213 
214   //No suggestion needed here
215   if(value7<value6){
216     value6 = value7;
217   }
218 
219   //CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
220   //CHECK-FIXES: value1 = std::min(value8, value1);
221   const int value8 = 5;
222   if(value8<value1)
223     value1 = value8;
224 
225   //CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
226   //CHECK-FIXES: value1 = std::min(value9, value1);
227   volatile int value9 = 6;
228   if(value9<value1)
229     value1 = value9;
230 }
231 
232 using my_size = unsigned long long;
233 
234 template<typename T>
235 struct MyVector
236 {
237     using size_type = my_size;
238     size_type size() const;
239 };
240 
241 void testVectorSizeType() {
242   MyVector<int> v;
243   unsigned int value;
244 
245   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
246   // CHECK-FIXES: value = std::max<my_size>(v.size(), value);
247   if (v.size() > value)
248     value = v.size();
249 
250   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
251   // CHECK-FIXES: value = std::max<my_size>(value, v.size());
252   if (value < v.size())
253     value = v.size();
254 }
255 
256 namespace gh121676 {
257 
258 void useLeft() {
259   using U16 = unsigned short;
260   U16 I = 0;
261   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
262   // CHECK-FIXES: I = std::max<U16>(I, 16U);
263   if (I < 16U)
264     I = 16U;
265 }
266 void useRight() {
267   using U16 = unsigned short;
268   U16 I = 0;
269   // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
270   // CHECK-FIXES: I = std::min<U16>(16U, I);
271   if (16U < I)
272     I = 16U;
273 }
274 
275 } // namespace gh121676
276