Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[ASTMatchers] Fix matching CXXOperatorCallExpr of -> #139994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
Loading
from

Conversation

tJener
Copy link
Contributor

@tJener tJener commented May 15, 2025

The -> operator does not have a corresponding UnaryOperatorKind, and so was unsupported by the hasOperatorName and hasUnaryOperand matchers.

Instead of trying to determine the equivalent unary or binary operator and then deriving the opcode string, we consult OperatorKinds.def directly (through getOperatorSpelling).

For hasUnaryOperand support, we special case the arrow operator specifically.

@tJener tJener requested a review from ymand May 15, 2025 03:38
@llvmbot llvmbot added the clang Clang issues not falling into any other category label May 15, 2025
@llvmbot
Copy link
Member

llvmbot commented May 15, 2025

@llvm/pr-subscribers-clang

Author: Eric Li (tJener)

Changes

The -> operator does not have a corresponding UnaryOperatorKind, and so was unsupported by the hasOperatorName and hasUnaryOperand matchers.

Instead of trying to determine the equivalent unary or binary operator and then deriving the opcode string, we consult OperatorKinds.def directly (through getOperatorSpelling).

For hasUnaryOperand support, we special case the arrow operator specifically.


Full diff: https://github.com/llvm/llvm-project/pull/139994.diff

2 Files Affected:

  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+9-17)
  • (modified) clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (+19-4)
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 71dfc49b7fcca..4a27a5d099e60 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -2161,8 +2161,10 @@ inline const Expr *getSubExpr(const NodeType &Node) {
 template <>
 inline const Expr *
 getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
-  if (!internal::equivalentUnaryOperator(Node))
+  if (!internal::equivalentUnaryOperator(Node) &&
+      Node.getOperator() != OO_Arrow) {
     return nullptr;
+  }
   return Node.getArg(0);
 }
 
@@ -2223,14 +2225,9 @@ inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
   return Node.getOpcodeStr();
 }
 inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
-  auto optBinaryOpcode = equivalentBinaryOperator(Node);
-  if (!optBinaryOpcode) {
-    auto optUnaryOpcode = equivalentUnaryOperator(Node);
-    if (!optUnaryOpcode)
-      return std::nullopt;
-    return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
-  }
-  return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
+  if (const char *Str = getOperatorSpelling(Node.getOperator()))
+    return Str;
+  return std::nullopt;
 }
 inline StringRef getOpName(const CXXFoldExpr &Node) {
   return BinaryOperator::getOpcodeStr(Node.getOperator());
@@ -2271,14 +2268,9 @@ class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
     return Node.getOpcodeStr();
   }
   static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
-    auto optBinaryOpcode = equivalentBinaryOperator(Node);
-    if (!optBinaryOpcode) {
-      auto optUnaryOpcode = equivalentUnaryOperator(Node);
-      if (!optUnaryOpcode)
-        return std::nullopt;
-      return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
-    }
-    return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
+    if (const char *Str = getOperatorSpelling(Node.getOperator()))
+      return Str;
+    return std::nullopt;
   }
 
   std::vector<std::string> Names;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 8759811092b6f..8ddae4e47004b 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -2025,14 +2025,24 @@ void plusIntOperator()
                          hasOperatorName("+"), hasUnaryOperand(expr())))));
 
   Code = R"cpp(
-struct HasOpArrow
+struct S {
+  void foo(int);
+};
+struct HasOpStar
 {
     int& operator*();
 };
-void foo()
+struct HasOpArrow
 {
-    HasOpArrow s1;
-    *s1;
+    S* operator->();
+};
+void hasOpStarMem(HasOpStar s)
+{
+    *s;
+}
+void hasOpArrowMem(HasOpArrow a)
+{
+    a->foo(42);
 }
 )cpp";
 
@@ -2040,6 +2050,11 @@ void foo()
       matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
                              cxxOperatorCallExpr(hasOperatorName("*"),
                                                  hasUnaryOperand(expr())))));
+  EXPECT_TRUE(matches(
+      Code, traverse(TK_IgnoreUnlessSpelledInSource,
+                     cxxOperatorCallExpr(hasOperatorName("->"),
+                                         hasUnaryOperand(declRefExpr(
+                                             to(varDecl(hasName("a")))))))));
 }
 
 TEST(Matcher, UnaryOperatorTypes) {

The `->` operator does not have a corresponding `UnaryOperatorKind`,
and so was unsupported by the `hasOperatorName` and `hasUnaryOperand`
matchers.

Instead of trying to determine the equivalent unary or binary operator
and then deriving the opcode string, we consult `OperatorKinds.def`
directly (through `getOperatorSpelling`).

For `hasUnaryOperand` support, we special case the arrow operator
specifically.
@tJener tJener force-pushed the fix-has-operator-name branch from c081799 to fdaba64 Compare May 15, 2025 03:38
@tJener tJener changed the title [ASTMatchers] Fix matching CXXOperatorCallExpr of -> [ASTMatchers] Fix matching CXXOperatorCallExpr of -> May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.