xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.c (revision e8a3ddafe063c970df9c23e803812369abde4c82)
189a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
289a1d03eSRichard // RUN: -config='{CheckOptions: \
3*e8a3ddafSNathan James // RUN:  {bugprone-suspicious-string-compare.WarnOnImplicitComparison: true, \
4*e8a3ddafSNathan James // RUN:   bugprone-suspicious-string-compare.WarnOnLogicalNotComparison: true}}' \
589a1d03eSRichard // RUN: -- -std=c99
689a1d03eSRichard 
789a1d03eSRichard static const char A[] = "abc";
889a1d03eSRichard 
989a1d03eSRichard int strcmp(const char *, const char *);
1089a1d03eSRichard 
test_warning_patterns(void)1189a1d03eSRichard int test_warning_patterns(void) {
1289a1d03eSRichard   if (strcmp(A, "a"))
1389a1d03eSRichard     return 0;
1489a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
1589a1d03eSRichard   // CHECK-FIXES: if (strcmp(A, "a") != 0)
1689a1d03eSRichard 
1789a1d03eSRichard   if (strcmp(A, "a") != 0 ||
1889a1d03eSRichard       strcmp(A, "b"))
1989a1d03eSRichard     return 0;
2089a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
2189a1d03eSRichard   // CHECK-FIXES: strcmp(A, "b") != 0)
2289a1d03eSRichard 
2389a1d03eSRichard   if (strcmp(A, "a") == 1)
2489a1d03eSRichard     return 0;
2589a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
2689a1d03eSRichard 
2789a1d03eSRichard   if (strcmp(A, "a") == -1)
2889a1d03eSRichard     return 0;
2989a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
3089a1d03eSRichard 
3189a1d03eSRichard   if (strcmp(A, "a") < '0')
3289a1d03eSRichard     return 0;
3389a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
3489a1d03eSRichard 
3589a1d03eSRichard   if (strcmp(A, "a") < 0.)
3689a1d03eSRichard     return 0;
3789a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
3889a1d03eSRichard 
3989a1d03eSRichard   if (!strcmp(A, "a"))
4089a1d03eSRichard     return 0;
4189a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-2]]:8: warning: function 'strcmp' is compared using logical not operator
4289a1d03eSRichard   // CHECK-FIXES: if (strcmp(A, "a") == 0)
4389a1d03eSRichard }
4489a1d03eSRichard 
test_structure_patterns(void)4589a1d03eSRichard void test_structure_patterns(void) {
4689a1d03eSRichard   if (strcmp(A, "a")) {}
4789a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: function 'strcmp' is called without explicitly comparing result
4889a1d03eSRichard   // CHECK-FIXES: if (strcmp(A, "a") != 0) {}
4989a1d03eSRichard 
5089a1d03eSRichard   while (strcmp(A, "a")) {}
5189a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: function 'strcmp' is called without explicitly comparing result
5289a1d03eSRichard   // CHECK-FIXES: while (strcmp(A, "a") != 0) {}
5389a1d03eSRichard 
5489a1d03eSRichard   for (;strcmp(A, "a");) {}
5589a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:9: warning: function 'strcmp' is called without explicitly comparing result
5689a1d03eSRichard   // CHECK-FIXES: for (;strcmp(A, "a") != 0;) {}
5789a1d03eSRichard }
5889a1d03eSRichard 
test_valid_patterns(void)5989a1d03eSRichard int test_valid_patterns(void) {
6089a1d03eSRichard   // The following cases are valid.
6189a1d03eSRichard   if (strcmp(A, "a") < 0) return 0;
6289a1d03eSRichard   if (strcmp(A, "a") == 0) return 0;
6389a1d03eSRichard   if (strcmp(A, "a") <= 0) return 0;
6489a1d03eSRichard   if (strcmp(A, "a") == strcmp(A, "b")) return 0;
6589a1d03eSRichard   return 1;
6689a1d03eSRichard }
6789a1d03eSRichard 
wrapper(const char * a,const char * b)6889a1d03eSRichard int wrapper(const char* a, const char* b) {
6989a1d03eSRichard   return strcmp(a, b);
7089a1d03eSRichard }
7189a1d03eSRichard 
assignment_wrapper(const char * a,const char * b)7289a1d03eSRichard int assignment_wrapper(const char* a, const char* b) {
7389a1d03eSRichard   int cmp = strcmp(a, b);
7489a1d03eSRichard   return cmp;
7589a1d03eSRichard }
7689a1d03eSRichard 
condexpr_wrapper(const char * a,const char * b)7789a1d03eSRichard int condexpr_wrapper(const char* a, const char* b) {
7889a1d03eSRichard   return (a < b) ? strcmp(a, b) : strcmp(b, a);
7989a1d03eSRichard }
80