1// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-suspicious-string-compare %t -- \
2// RUN: -config='{CheckOptions: \
3// RUN: {bugprone-suspicious-string-compare.WarnOnImplicitComparison: true, \
4// RUN: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison: true}}' \
5// RUN: --
6
7typedef __SIZE_TYPE__ size;
8
9struct locale_t {
10 void* dummy;
11} locale;
12
13static const char A[] = "abc";
14static const unsigned char U[] = "abc";
15static const unsigned char V[] = "xyz";
16static const wchar_t W[] = L"abc";
17
18int strlen(const char *);
19
20int memcmp(const void *, const void *, size);
21int wmemcmp(const wchar_t *, const wchar_t *, size);
22int memicmp(const void *, const void *, size);
23int _memicmp(const void *, const void *, size);
24int _memicmp_l(const void *, const void *, size, locale_t);
25
26int strcmp(const char *, const char *);
27int strncmp(const char *, const char *, size);
28int strcasecmp(const char *, const char *);
29int strncasecmp(const char *, const char *, size);
30int stricmp(const char *, const char *);
31int strcmpi(const char *, const char *);
32int strnicmp(const char *, const char *, size);
33int _stricmp(const char *, const char * );
34int _strnicmp(const char *, const char *, size);
35int _stricmp_l(const char *, const char *, locale_t);
36int _strnicmp_l(const char *, const char *, size, locale_t);
37
38int wcscmp(const wchar_t *, const wchar_t *);
39int wcsncmp(const wchar_t *, const wchar_t *, size);
40int wcscasecmp(const wchar_t *, const wchar_t *);
41int wcsicmp(const wchar_t *, const wchar_t *);
42int wcsnicmp(const wchar_t *, const wchar_t *, size);
43int _wcsicmp(const wchar_t *, const wchar_t *);
44int _wcsnicmp(const wchar_t *, const wchar_t *, size);
45int _wcsicmp_l(const wchar_t *, const wchar_t *, locale_t);
46int _wcsnicmp_l(const wchar_t *, const wchar_t *, size, locale_t);
47
48int _mbscmp(const unsigned char *, const unsigned char *);
49int _mbsncmp(const unsigned char *, const unsigned char *, size);
50int _mbsnbcmp(const unsigned char *, const unsigned char *, size);
51int _mbsnbicmp(const unsigned char *, const unsigned char *, size);
52int _mbsicmp(const unsigned char *, const unsigned char *);
53int _mbsnicmp(const unsigned char *, const unsigned char *, size);
54int _mbscmp_l(const unsigned char *, const unsigned char *, locale_t);
55int _mbsncmp_l(const unsigned char *, const unsigned char *, size, locale_t);
56int _mbsicmp_l(const unsigned char *, const unsigned char *, locale_t);
57int _mbsnicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
58int _mbsnbcmp_l(const unsigned char *, const unsigned char *, size, locale_t);
59int _mbsnbicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
60
61int test_warning_patterns() {
62 if (strcmp(A, "a"))
63 return 0;
64 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
65 // CHECK-FIXES: if (strcmp(A, "a") != 0)
66
67 if (strcmp(A, "a") == 0 ||
68 strcmp(A, "b"))
69 return 0;
70 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
71 // CHECK-FIXES: strcmp(A, "b") != 0)
72
73 if (strcmp(A, "a") == 1)
74 return 0;
75 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
76
77 if (strcmp(A, "a") == -1)
78 return 0;
79 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
80
81 if (strcmp(A, "a") == true)
82 return 0;
83 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
84
85 if (strcmp(A, "a") < '0')
86 return 0;
87 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
88
89 if (strcmp(A, "a") < 0.)
90 return 0;
91 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
92
93 return 1;
94}
95
96int test_valid_patterns() {
97 // The following cases are valid.
98 if (strcmp(A, "a") < 0)
99 return 0;
100 if (strcmp(A, "a") == 0)
101 return 0;
102 if (strcmp(A, "a") <= 0)
103 return 0;
104
105 if (wcscmp(W, L"a") < 0)
106 return 0;
107 if (wcscmp(W, L"a") == 0)
108 return 0;
109 if (wcscmp(W, L"a") <= 0)
110 return 0;
111
112 return 1;
113}
114
115int test_implicit_compare_with_functions() {
116
117 if (memcmp(A, "a", 1))
118 return 0;
119 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memcmp' is called without explicitly comparing result
120 // CHECK-FIXES: memcmp(A, "a", 1) != 0)
121
122 if (wmemcmp(W, L"a", 1))
123 return 0;
124 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wmemcmp' is called without explicitly comparing result
125 // CHECK-FIXES: wmemcmp(W, L"a", 1) != 0)
126
127 if (memicmp(A, "a", 1))
128 return 0;
129 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memicmp' is called without explicitly comparing result
130 // CHECK-FIXES: memicmp(A, "a", 1) != 0)
131
132 if (_memicmp(A, "a", 1))
133 return 0;
134 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp' is called without explicitly comparing result
135 // CHECK-FIXES: _memicmp(A, "a", 1) != 0)
136
137 if (_memicmp_l(A, "a", 1, locale))
138 return 0;
139 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp_l' is called without explicitly comparing result
140 // CHECK-FIXES: _memicmp_l(A, "a", 1, locale) != 0)
141
142 if (strcmp(A, "a"))
143 return 0;
144 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
145 // CHECK-FIXES: strcmp(A, "a") != 0)
146
147 if (strncmp(A, "a", 1))
148 return 0;
149 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result
150 // CHECK-FIXES: strncmp(A, "a", 1) != 0)
151
152 if (strcasecmp(A, "a"))
153 return 0;
154 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcasecmp' is called without explicitly comparing result
155 // CHECK-FIXES: strcasecmp(A, "a") != 0)
156
157 if (strncasecmp(A, "a", 1))
158 return 0;
159 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncasecmp' is called without explicitly comparing result
160 // CHECK-FIXES: strncasecmp(A, "a", 1) != 0)
161
162 if (stricmp(A, "a"))
163 return 0;
164 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'stricmp' is called without explicitly comparing result
165 // CHECK-FIXES: stricmp(A, "a") != 0)
166
167 if (strcmpi(A, "a"))
168 return 0;
169 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmpi' is called without explicitly comparing result
170 // CHECK-FIXES: strcmpi(A, "a") != 0)
171
172 if (_stricmp(A, "a"))
173 return 0;
174 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp' is called without explicitly comparing result
175 // CHECK-FIXES: _stricmp(A, "a") != 0)
176
177 if (strnicmp(A, "a", 1))
178 return 0;
179 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strnicmp' is called without explicitly comparing result
180 // CHECK-FIXES: strnicmp(A, "a", 1) != 0)
181
182 if (_strnicmp(A, "a", 1))
183 return 0;
184 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp' is called without explicitly comparing result
185 // CHECK-FIXES: _strnicmp(A, "a", 1) != 0)
186
187 if (_stricmp_l(A, "a", locale))
188 return 0;
189 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp_l' is called without explicitly comparing result
190 // CHECK-FIXES: _stricmp_l(A, "a", locale) != 0)
191
192 if (_strnicmp_l(A, "a", 1, locale))
193 return 0;
194 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp_l' is called without explicitly comparing result
195 // CHECK-FIXES: _strnicmp_l(A, "a", 1, locale) != 0)
196
197 if (wcscmp(W, L"a"))
198 return 0;
199 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscmp' is called without explicitly comparing result
200 // CHECK-FIXES: wcscmp(W, L"a") != 0)
201
202 if (wcsncmp(W, L"a", 1))
203 return 0;
204 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsncmp' is called without explicitly comparing result
205 // CHECK-FIXES: wcsncmp(W, L"a", 1) != 0)
206
207 if (wcscasecmp(W, L"a"))
208 return 0;
209 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscasecmp' is called without explicitly comparing result
210 // CHECK-FIXES: wcscasecmp(W, L"a") != 0)
211
212 if (wcsicmp(W, L"a"))
213 return 0;
214 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsicmp' is called without explicitly comparing result
215 // CHECK-FIXES: wcsicmp(W, L"a") != 0)
216
217 if (_wcsicmp(W, L"a"))
218 return 0;
219 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp' is called without explicitly comparing result
220 // CHECK-FIXES: _wcsicmp(W, L"a") != 0)
221
222 if (_wcsicmp_l(W, L"a", locale))
223 return 0;
224 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp_l' is called without explicitly comparing result
225 // CHECK-FIXES: _wcsicmp_l(W, L"a", locale) != 0)
226
227 if (wcsnicmp(W, L"a", 1))
228 return 0;
229 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsnicmp' is called without explicitly comparing result
230 // CHECK-FIXES: wcsnicmp(W, L"a", 1) != 0)
231
232 if (_wcsnicmp(W, L"a", 1))
233 return 0;
234 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp' is called without explicitly comparing result
235 // CHECK-FIXES: _wcsnicmp(W, L"a", 1) != 0)
236
237 if (_wcsnicmp_l(W, L"a", 1, locale))
238 return 0;
239 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp_l' is called without explicitly comparing result
240 // CHECK-FIXES: _wcsnicmp_l(W, L"a", 1, locale) != 0)
241
242 if (_mbscmp(U, V))
243 return 0;
244 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp' is called without explicitly comparing result
245 // CHECK-FIXES: _mbscmp(U, V) != 0)
246
247 if (_mbsncmp(U, V, 1))
248 return 0;
249 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp' is called without explicitly comparing result
250 // CHECK-FIXES: _mbsncmp(U, V, 1) != 0)
251
252 if (_mbsnbcmp(U, V, 1))
253 return 0;
254 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp' is called without explicitly comparing result
255 // CHECK-FIXES: _mbsnbcmp(U, V, 1) != 0)
256
257 if (_mbsnbicmp(U, V, 1))
258 return 0;
259 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp' is called without explicitly comparing result
260 // CHECK-FIXES: _mbsnbicmp(U, V, 1) != 0)
261
262 if (_mbsicmp(U, V))
263 return 0;
264 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp' is called without explicitly comparing result
265 // CHECK-FIXES: _mbsicmp(U, V) != 0)
266
267 if (_mbsnicmp(U, V, 1))
268 return 0;
269 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp' is called without explicitly comparing result
270 // CHECK-FIXES: _mbsnicmp(U, V, 1) != 0)
271
272 if (_mbscmp_l(U, V, locale))
273 return 0;
274 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp_l' is called without explicitly comparing result
275 // CHECK-FIXES: _mbscmp_l(U, V, locale) != 0)
276
277 if (_mbsncmp_l(U, V, 1, locale))
278 return 0;
279 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp_l' is called without explicitly comparing result
280 // CHECK-FIXES: _mbsncmp_l(U, V, 1, locale) != 0)
281
282 if (_mbsicmp_l(U, V, locale))
283 return 0;
284 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp_l' is called without explicitly comparing result
285 // CHECK-FIXES: _mbsicmp_l(U, V, locale) != 0)
286
287 if (_mbsnicmp_l(U, V, 1, locale))
288 return 0;
289 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp_l' is called without explicitly comparing result
290 // CHECK-FIXES: _mbsnicmp_l(U, V, 1, locale) != 0)
291
292 if (_mbsnbcmp_l(U, V, 1, locale))
293 return 0;
294 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp_l' is called without explicitly comparing result
295 // CHECK-FIXES: _mbsnbcmp_l(U, V, 1, locale) != 0)
296
297 if (_mbsnbicmp_l(U, V, 1, locale))
298 return 0;
299 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp_l' is called without explicitly comparing result
300 // CHECK-FIXES: _mbsnbicmp_l(U, V, 1, locale) != 0)
301
302 return 1;
303}
304
305int strcmp_wrapper1(const char* a, const char* b) {
306 return strcmp(a, b);
307}
308
309int strcmp_wrapper2(const char* a, const char* b) {
310 return (a && b) ? strcmp(a, b) : 0;
311}
312
313#define macro_strncmp(s1, s2, n) \
314 (__extension__ (__builtin_constant_p (n) \
315 && ((__builtin_constant_p (s1) \
316 && strlen (s1) < ((size) (n))) \
317 || (__builtin_constant_p (s2) \
318 && strlen (s2) < ((size) (n)))) \
319 ? strcmp (s1, s2) : strncmp (s1, s2, n)))
320
321int strncmp_macro(const char* a, const char* b) {
322 if (macro_strncmp(a, b, 4))
323 return 0;
324 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
325
326 if (macro_strncmp(a, b, 4) == 2)
327 return 0;
328 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
329
330 if (macro_strncmp(a, b, 4) <= .0)
331 return 0;
332 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
333
334 if (macro_strncmp(a, b, 4) + 0)
335 return 0;
336 // CHECK-MESSAGES: [[@LINE-2]]:7: warning: results of function 'strcmp' used by operator '+'
337
338 return 1;
339}
340

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp