1 // RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
2 // RUN: -config='{CheckOptions: \
3 // RUN:  [{key: bugprone-suspicious-string-compare.WarnOnImplicitComparison, value: true}, \
4 // RUN:   {key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison, value: true}]}' \
5 // RUN: -- -std=c99
6 
7 static const char A[] = "abc";
8 
9 int strcmp(const char *, const char *);
10 
test_warning_patterns()11 int test_warning_patterns() {
12   if (strcmp(A, "a"))
13     return 0;
14   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
15   // CHECK-FIXES: if (strcmp(A, "a") != 0)
16 
17   if (strcmp(A, "a") != 0 ||
18       strcmp(A, "b"))
19     return 0;
20   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
21   // CHECK-FIXES: strcmp(A, "b") != 0)
22 
23   if (strcmp(A, "a") == 1)
24     return 0;
25   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
26 
27   if (strcmp(A, "a") == -1)
28     return 0;
29   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
30 
31   if (strcmp(A, "a") < '0')
32     return 0;
33   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
34 
35   if (strcmp(A, "a") < 0.)
36     return 0;
37   // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
38 
39   if (!strcmp(A, "a"))
40     return 0;
41   // CHECK-MESSAGES: [[@LINE-2]]:8: warning: function 'strcmp' is compared using logical not operator
42   // CHECK-FIXES: if (strcmp(A, "a") == 0)
43 }
44 
test_structure_patterns()45 void test_structure_patterns() {
46   if (strcmp(A, "a")) {}
47   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: function 'strcmp' is called without explicitly comparing result
48   // CHECK-FIXES: if (strcmp(A, "a") != 0) {}
49 
50   while (strcmp(A, "a")) {}
51   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: function 'strcmp' is called without explicitly comparing result
52   // CHECK-FIXES: while (strcmp(A, "a") != 0) {}
53 
54   for (;strcmp(A, "a");) {}
55   // CHECK-MESSAGES: [[@LINE-1]]:9: warning: function 'strcmp' is called without explicitly comparing result
56   // CHECK-FIXES: for (;strcmp(A, "a") != 0;) {}
57 }
58 
test_valid_patterns()59 int test_valid_patterns() {
60   // The following cases are valid.
61   if (strcmp(A, "a") < 0) return 0;
62   if (strcmp(A, "a") == 0) return 0;
63   if (strcmp(A, "a") <= 0) return 0;
64   if (strcmp(A, "a") == strcmp(A, "b")) return 0;
65   return 1;
66 }
67 
wrapper(const char * a,const char * b)68 int wrapper(const char* a, const char* b) {
69   return strcmp(a, b);
70 }
71 
assignment_wrapper(const char * a,const char * b)72 int assignment_wrapper(const char* a, const char* b) {
73   int cmp = strcmp(a, b);
74   return cmp;
75 }
76 
condexpr_wrapper(const char * a,const char * b)77 int condexpr_wrapper(const char* a, const char* b) {
78   return (a < b) ? strcmp(a, b) : strcmp(b, a);
79 }
80