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