Skip to content

Commit 032b33e

Browse files
committed
[clang-tidy][readability-container-contains] Fix matching of non-binaryOperator cases
Fix #79437. It works with non-mock `std::map`: ``` # All cases detailed in #79437. > cat tmp.cpp #include <map> bool a(std::map<int, int> &m, int key) { return m.find(key) != m.end(); } bool b(std::map<int, int> &m, int key) { return m.count(key) > 0; } bool c(std::map<int, int> &m, int key) { return m.find(key) == m.end(); } bool d(std::map<int, int> &m, int key) { return m.count(key) == 0; } bool e(std::map<int, int> *m, int key) { return m->find(key) != m->end(); } bool f(std::map<int, int> *m, int key) { return m->find(key) == m->end(); } bool g(std::map<int, int> *m, int key) { return m->count(key) > 0; } bool h(std::map<int, int> *m, int key) { return m->count(key) == 0; } > ./build/bin/clang-tidy -checks="-*,readability-container-contains" tmp.cpp -- -std=c++20 8 warnings generated. tmp.cpp:2:51: warning: use 'contains' to check for membership [readability-container-contains] 2 | bool a(std::map<int, int> &m, int key) { return m.find(key) != m.end(); } | ^~~~ ~~~~~~~~~~ | contains tmp.cpp:3:51: warning: use 'contains' to check for membership [readability-container-contains] 3 | bool b(std::map<int, int> &m, int key) { return m.count(key) > 0; } | ^~~~~ ~~~ | contains tmp.cpp:4:51: warning: use 'contains' to check for membership [readability-container-contains] 4 | bool c(std::map<int, int> &m, int key) { return m.find(key) == m.end(); } | ^~~~ ~~~~~~~~~~ | ! contains tmp.cpp:5:51: warning: use 'contains' to check for membership [readability-container-contains] 5 | bool d(std::map<int, int> &m, int key) { return m.count(key) == 0; } | ^~~~~ ~~~~ | ! contains tmp.cpp:6:52: warning: use 'contains' to check for membership [readability-container-contains] 6 | bool e(std::map<int, int> *m, int key) { return m->find(key) != m->end(); } | ^~~~ ~~~~~~~~~~~ | contains tmp.cpp:7:52: warning: use 'contains' to check for membership [readability-container-contains] 7 | bool f(std::map<int, int> *m, int key) { return m->find(key) == m->end(); } | ^~~~ ~~~~~~~~~~~ | ! contains tmp.cpp:8:52: warning: use 'contains' to check for membership [readability-container-contains] 8 | bool g(std::map<int, int> *m, int key) { return m->count(key) > 0; } | ^~~~~ ~~~ | contains tmp.cpp:9:52: warning: use 'contains' to check for membership [readability-container-contains] 9 | bool h(std::map<int, int> *m, int key) { return m->count(key) == 0; } | ^~~~~ ~~~~ | ! contains ```
1 parent 6022a3a commit 032b33e

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,44 +62,44 @@ void ContainerContainsCheck::registerMatchers(MatchFinder *Finder) {
6262
.bind("positiveComparison"),
6363
this);
6464
AddSimpleMatcher(
65-
binaryOperator(hasOperatorName("!="), hasOperands(CountCall, Literal0))
65+
binaryOperation(hasOperatorName("!="), hasOperands(CountCall, Literal0))
6666
.bind("positiveComparison"));
6767
AddSimpleMatcher(
68-
binaryOperator(hasLHS(CountCall), hasOperatorName(">"), hasRHS(Literal0))
68+
binaryOperation(hasLHS(CountCall), hasOperatorName(">"), hasRHS(Literal0))
6969
.bind("positiveComparison"));
7070
AddSimpleMatcher(
71-
binaryOperator(hasLHS(Literal0), hasOperatorName("<"), hasRHS(CountCall))
72-
.bind("positiveComparison"));
73-
AddSimpleMatcher(
74-
binaryOperator(hasLHS(CountCall), hasOperatorName(">="), hasRHS(Literal1))
75-
.bind("positiveComparison"));
76-
AddSimpleMatcher(
77-
binaryOperator(hasLHS(Literal1), hasOperatorName("<="), hasRHS(CountCall))
71+
binaryOperation(hasLHS(Literal0), hasOperatorName("<"), hasRHS(CountCall))
7872
.bind("positiveComparison"));
73+
AddSimpleMatcher(binaryOperation(hasLHS(CountCall), hasOperatorName(">="),
74+
hasRHS(Literal1))
75+
.bind("positiveComparison"));
76+
AddSimpleMatcher(binaryOperation(hasLHS(Literal1), hasOperatorName("<="),
77+
hasRHS(CountCall))
78+
.bind("positiveComparison"));
7979

8080
// Find inverted membership tests which use `count()`.
8181
AddSimpleMatcher(
82-
binaryOperator(hasOperatorName("=="), hasOperands(CountCall, Literal0))
83-
.bind("negativeComparison"));
84-
AddSimpleMatcher(
85-
binaryOperator(hasLHS(CountCall), hasOperatorName("<="), hasRHS(Literal0))
86-
.bind("negativeComparison"));
87-
AddSimpleMatcher(
88-
binaryOperator(hasLHS(Literal0), hasOperatorName(">="), hasRHS(CountCall))
82+
binaryOperation(hasOperatorName("=="), hasOperands(CountCall, Literal0))
8983
.bind("negativeComparison"));
84+
AddSimpleMatcher(binaryOperation(hasLHS(CountCall), hasOperatorName("<="),
85+
hasRHS(Literal0))
86+
.bind("negativeComparison"));
87+
AddSimpleMatcher(binaryOperation(hasLHS(Literal0), hasOperatorName(">="),
88+
hasRHS(CountCall))
89+
.bind("negativeComparison"));
9090
AddSimpleMatcher(
91-
binaryOperator(hasLHS(CountCall), hasOperatorName("<"), hasRHS(Literal1))
91+
binaryOperation(hasLHS(CountCall), hasOperatorName("<"), hasRHS(Literal1))
9292
.bind("negativeComparison"));
9393
AddSimpleMatcher(
94-
binaryOperator(hasLHS(Literal1), hasOperatorName(">"), hasRHS(CountCall))
94+
binaryOperation(hasLHS(Literal1), hasOperatorName(">"), hasRHS(CountCall))
9595
.bind("negativeComparison"));
9696

9797
// Find membership tests based on `find() == end()`.
9898
AddSimpleMatcher(
99-
binaryOperator(hasOperatorName("!="), hasOperands(FindCall, EndCall))
99+
binaryOperation(hasOperatorName("!="), hasOperands(FindCall, EndCall))
100100
.bind("positiveComparison"));
101101
AddSimpleMatcher(
102-
binaryOperator(hasOperatorName("=="), hasOperands(FindCall, EndCall))
102+
binaryOperation(hasOperatorName("=="), hasOperands(FindCall, EndCall))
103103
.bind("negativeComparison"));
104104
}
105105

clang-tools-extra/test/clang-tidy/checkers/readability/container-contains.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
// RUN: %check_clang_tidy -std=c++20-or-later %s readability-container-contains %t
1+
// RUN: %check_clang_tidy -std=c++11-or-later %s readability-container-contains %t
22

33
// Some *very* simplified versions of `map` etc.
44
namespace std {
55

66
template <class Key, class T>
77
struct map {
8+
struct iterator {
9+
bool operator==(const iterator &Other) const;
10+
bool operator!=(const iterator &Other) const;
11+
};
12+
813
unsigned count(const Key &K) const;
914
bool contains(const Key &K) const;
10-
void *find(const Key &K);
11-
void *end();
15+
iterator find(const Key &K);
16+
iterator end();
1217
};
1318

1419
template <class Key>

0 commit comments

Comments
 (0)