[clang-tools-extra] [clang-tidy] Enhance modernize-use-starts-ends-with to handle substr patterns (PR #116033)

Helmut Januschka via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 16 03:10:14 PST 2024


================
@@ -189,7 +203,54 @@ void UseStartsEndsWithCheck::check(const MatchFinder::MatchResult &Result) {
   if (ComparisonExpr->getBeginLoc().isMacroID())
     return;
 
-  const bool Neg = ComparisonExpr->getOpcode() == BO_NE;
+  bool Neg;
+  if (const auto *BO = llvm::dyn_cast<BinaryOperator>(ComparisonExpr)) {
+    Neg = BO->getOpcode() == BO_NE;
+  } else {
+    assert(llvm::isa<CXXOperatorCallExpr>(ComparisonExpr));
+    Neg = llvm::cast<CXXOperatorCallExpr>(ComparisonExpr)->getOperator() ==
+          OO_ExclaimEqual;
+  }
----------------
hjanuschka wrote:

added `isNegativeComparison`

```c++
bool UseStartsEndsWithCheck::isNegativeComparison(const Expr* ComparisonExpr) {
  // Handle direct != operator
  if (const auto *BO = llvm::dyn_cast<BinaryOperator>(ComparisonExpr)) {
    return BO->getOpcode() == BO_NE;
  }
  
  // Handle operator!= call
  if (const auto *Op = llvm::dyn_cast<CXXOperatorCallExpr>(ComparisonExpr)) {
    return Op->getOperator() == OO_ExclaimEqual;
  }
  
  // Handle rewritten !(expr == expr)
  if (const auto *UO = llvm::dyn_cast<UnaryOperator>(ComparisonExpr)) {
    if (UO->getOpcode() == UO_LNot) {
      if (const auto *InnerBO = 
          llvm::dyn_cast<BinaryOperator>(UO->getSubExpr()->IgnoreParens())) {
        return InnerBO->getOpcode() == BO_EQ;
      }
      if (const auto *InnerOp = 
          llvm::dyn_cast<CXXOperatorCallExpr>(UO->getSubExpr()->IgnoreParens())) {
        return InnerOp->getOperator() == OO_EqualEqual;
      }
    }
  }
  
  return false;
}
```

and some tests:
```
    // Test != operator rewriting
    str.substr(0, 5) != "hello";
    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr != [modernize-use-starts-ends-with]
    // CHECK-FIXES: !str.starts_with("hello");

    // Test rewritten form
    !(str.substr(0, 5) == "hello");
    // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr == [modernize-use-starts-ends-with]
```

https://github.com/llvm/llvm-project/pull/116033


More information about the cfe-commits mailing list