Skip to content

Commit fc3c80c

Browse files
committed
[ASTMatchers] adds isComparisonOperator to BinaryOperator and CXXOperatorCallExpr
Reviewers: aaron.ballman, gribozavr2 Reviewed By: aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75800
1 parent 073dbaa commit fc3c80c

File tree

6 files changed

+86
-7
lines changed

6 files changed

+86
-7
lines changed

clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ matchRelationalIntegerConstantExpr(StringRef Id) {
567567
std::string OverloadId = (Id + "-overload").str();
568568

569569
const auto RelationalExpr = ignoringParenImpCasts(binaryOperator(
570-
isComparisonOperator(), expr().bind(Id),
570+
matchers::isComparisonOperator(), expr().bind(Id),
571571
anyOf(allOf(hasLHS(matchSymbolicExpr(Id)),
572572
hasRHS(matchIntegerConstantExpr(Id))),
573573
allOf(hasLHS(matchIntegerConstantExpr(Id)),
@@ -943,22 +943,22 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
943943
const auto SymRight = matchSymbolicExpr("rhs");
944944

945945
// Match expressions like: x <op> 0xFF == 0xF00.
946-
Finder->addMatcher(binaryOperator(isComparisonOperator(),
946+
Finder->addMatcher(binaryOperator(matchers::isComparisonOperator(),
947947
hasEitherOperand(BinOpCstLeft),
948948
hasEitherOperand(CstRight))
949949
.bind("binop-const-compare-to-const"),
950950
this);
951951

952952
// Match expressions like: x <op> 0xFF == x.
953953
Finder->addMatcher(
954-
binaryOperator(isComparisonOperator(),
954+
binaryOperator(matchers::isComparisonOperator(),
955955
anyOf(allOf(hasLHS(BinOpCstLeft), hasRHS(SymRight)),
956956
allOf(hasLHS(SymRight), hasRHS(BinOpCstLeft))))
957957
.bind("binop-const-compare-to-sym"),
958958
this);
959959

960960
// Match expressions like: x <op> 10 == x <op> 12.
961-
Finder->addMatcher(binaryOperator(isComparisonOperator(),
961+
Finder->addMatcher(binaryOperator(matchers::isComparisonOperator(),
962962
hasLHS(BinOpCstLeft), hasRHS(BinOpCstRight),
963963
// Already reported as redundant.
964964
unless(operandsAreEquivalent()))

clang/docs/LibASTMatchersReference.html

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,7 +2157,21 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
21572157
Example 2: matches s1 = s2
21582158
(matcher = cxxOperatorCallExpr(isAssignmentOperator()))
21592159
struct S { S&amp; operator=(const S&amp;); };
2160-
void x() { S s1, s2; s1 = s2; })
2160+
void x() { S s1, s2; s1 = s2; }
2161+
</pre></td></tr>
2162+
2163+
2164+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('isComparisonOperator0')"><a name="isComparisonOperator0Anchor">isComparisonOperator</a></td><td></td></tr>
2165+
<tr><td colspan="4" class="doc" id="isComparisonOperator0"><pre>Matches comparison operators.
2166+
2167+
Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
2168+
if (a == b)
2169+
a += b;
2170+
2171+
Example 2: matches s1 &lt; s2
2172+
(matcher = cxxOperatorCallExpr(isComparisonOperator()))
2173+
struct S { bool operator&lt;(const S&amp; other); };
2174+
void x(S s1, S s2) { bool b1 = s1 &lt; s2; }
21612175
</pre></td></tr>
21622176

21632177

@@ -2616,7 +2630,21 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
26162630
Example 2: matches s1 = s2
26172631
(matcher = cxxOperatorCallExpr(isAssignmentOperator()))
26182632
struct S { S&amp; operator=(const S&amp;); };
2619-
void x() { S s1, s2; s1 = s2; })
2633+
void x() { S s1, s2; s1 = s2; }
2634+
</pre></td></tr>
2635+
2636+
2637+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;</td><td class="name" onclick="toggle('isComparisonOperator1')"><a name="isComparisonOperator1Anchor">isComparisonOperator</a></td><td></td></tr>
2638+
<tr><td colspan="4" class="doc" id="isComparisonOperator1"><pre>Matches comparison operators.
2639+
2640+
Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
2641+
if (a == b)
2642+
a += b;
2643+
2644+
Example 2: matches s1 &lt; s2
2645+
(matcher = cxxOperatorCallExpr(isComparisonOperator()))
2646+
struct S { bool operator&lt;(const S&amp; other); };
2647+
void x(S s1, S s2) { bool b1 = s1 &lt; s2; }
26202648
</pre></td></tr>
26212649

26222650

clang/include/clang/AST/ExprCXX.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ class CXXOperatorCallExpr final : public CallExpr {
118118
}
119119
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
120120

121+
static bool isComparisonOp(OverloadedOperatorKind Opc) {
122+
switch (Opc) {
123+
case OO_EqualEqual:
124+
case OO_ExclaimEqual:
125+
case OO_Greater:
126+
case OO_GreaterEqual:
127+
case OO_Less:
128+
case OO_LessEqual:
129+
case OO_Spaceship:
130+
return true;
131+
default:
132+
return false;
133+
}
134+
}
135+
bool isComparisonOp() const { return isComparisonOp(getOperator()); }
136+
121137
/// Is this written as an infix binary operator?
122138
bool isInfixBinaryOp() const;
123139

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4783,14 +4783,34 @@ extern const internal::VariadicFunction<
47834783
/// (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
47844784
/// \code
47854785
/// struct S { S& operator=(const S&); };
4786-
/// void x() { S s1, s2; s1 = s2; })
4786+
/// void x() { S s1, s2; s1 = s2; }
47874787
/// \endcode
47884788
AST_POLYMORPHIC_MATCHER(isAssignmentOperator,
47894789
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
47904790
CXXOperatorCallExpr)) {
47914791
return Node.isAssignmentOp();
47924792
}
47934793

4794+
/// Matches comparison operators.
4795+
///
4796+
/// Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
4797+
/// \code
4798+
/// if (a == b)
4799+
/// a += b;
4800+
/// \endcode
4801+
///
4802+
/// Example 2: matches s1 < s2
4803+
/// (matcher = cxxOperatorCallExpr(isComparisonOperator()))
4804+
/// \code
4805+
/// struct S { bool operator<(const S& other); };
4806+
/// void x(S s1, S s2) { bool b1 = s1 < s2; }
4807+
/// \endcode
4808+
AST_POLYMORPHIC_MATCHER(isComparisonOperator,
4809+
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
4810+
CXXOperatorCallExpr)) {
4811+
return Node.isComparisonOp();
4812+
}
4813+
47944814
/// Matches the left hand side of binary operator expressions.
47954815
///
47964816
/// Example matches a (matcher = binaryOperator(hasLHS()))

clang/lib/ASTMatchers/Dynamic/Registry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ RegistryMaps::RegistryMaps() {
358358
REGISTER_MATCHER(isClass);
359359
REGISTER_MATCHER(isClassMessage);
360360
REGISTER_MATCHER(isClassMethod);
361+
REGISTER_MATCHER(isComparisonOperator);
361362
REGISTER_MATCHER(isConst);
362363
REGISTER_MATCHER(isConstQualified);
363364
REGISTER_MATCHER(isConstexpr);

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2689,6 +2689,20 @@ TEST(IsAssignmentOperator, Basic) {
26892689
notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
26902690
}
26912691

2692+
TEST(IsComparisonOperator, Basic) {
2693+
StatementMatcher BinCompOperator = binaryOperator(isComparisonOperator());
2694+
StatementMatcher CXXCompOperator =
2695+
cxxOperatorCallExpr(isComparisonOperator());
2696+
2697+
EXPECT_TRUE(matches("void x() { int a; a == 1; }", BinCompOperator));
2698+
EXPECT_TRUE(matches("void x() { int a; a > 2; }", BinCompOperator));
2699+
EXPECT_TRUE(matches("struct S { bool operator==(const S&); };"
2700+
"void x() { S s1, s2; bool b1 = s1 == s2; }",
2701+
CXXCompOperator));
2702+
EXPECT_TRUE(
2703+
notMatches("void x() { int a; if(a = 0) return; }", BinCompOperator));
2704+
}
2705+
26922706
TEST(HasInit, Basic) {
26932707
EXPECT_TRUE(
26942708
matches("int x{0};",

0 commit comments

Comments
 (0)