From 559f3728441d4b8342c71ef554d84a2804575d9d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 19 Feb 2021 22:59:35 +0000 Subject: [PATCH] [ASTMatchers] Fix hasUnaryOperand matcher for postfix operators Differential Revision: https://reviews.llvm.org/D97095 --- .../clang/ASTMatchers/ASTMatchersInternal.h | 3 +- .../ASTMatchers/ASTMatchersTraversalTest.cpp | 78 ++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 2af4e6e..5e3af4a 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -2039,7 +2039,8 @@ equivalentUnaryOperator(const NodeType &Node) { template <> inline Optional equivalentUnaryOperator(const CXXOperatorCallExpr &Node) { - if (Node.getNumArgs() != 1) + if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus && + Node.getOperator() != OO_MinusMinus) return None; switch (Node.getOperator()) { default: diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 8a6e94c..9909cec 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1630,6 +1630,84 @@ void opFree() cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))), hasAnyOperatorName("+", "!"), hasUnaryOperand(s1Expr))))); + + Code = R"cpp( +struct HasIncOperatorsMem +{ + HasIncOperatorsMem& operator++(); + HasIncOperatorsMem operator++(int); +}; +struct HasIncOperatorsFree +{ +}; +HasIncOperatorsFree& operator++(HasIncOperatorsFree&); +HasIncOperatorsFree operator++(HasIncOperatorsFree&, int); + +void prefixIncOperatorMem() +{ + HasIncOperatorsMem s1; + ++s1; +} +void prefixIncOperatorFree() +{ + HasIncOperatorsFree s1; + ++s1; +} +void postfixIncOperatorMem() +{ + HasIncOperatorsMem s1; + s1++; +} +void postfixIncOperatorFree() +{ + HasIncOperatorsFree s1; + s1++; +} + +struct HasOpPlusInt +{ + HasOpPlusInt& operator+(int); +}; +void plusIntOperator() +{ + HasOpPlusInt s1; + s1+1; +} +)cpp"; + + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + cxxOperatorCallExpr( + forFunction(functionDecl(hasName("prefixIncOperatorMem"))), + hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); + + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + cxxOperatorCallExpr( + forFunction(functionDecl(hasName("prefixIncOperatorFree"))), + hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); + + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + cxxOperatorCallExpr( + forFunction(functionDecl(hasName("postfixIncOperatorMem"))), + hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); + + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + cxxOperatorCallExpr( + forFunction(functionDecl(hasName("postfixIncOperatorFree"))), + hasOperatorName("++"), hasUnaryOperand(declRefExpr()))))); + + EXPECT_FALSE(matches( + Code, traverse(TK_IgnoreUnlessSpelledInSource, + cxxOperatorCallExpr( + forFunction(functionDecl(hasName("plusIntOperator"))), + hasOperatorName("+"), hasUnaryOperand(expr()))))); } TEST(Matcher, UnaryOperatorTypes) { -- 2.7.4