jvikstrom created this revision.
jvikstrom added reviewers: hokein, gribozavr.
Herald added a subscriber: xazax.hun.
Herald added a project: clang.

Fixes the checker for abseil to make tests pass in C++17 mode


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63127

Files:
  clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
  clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
  clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp
  clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
  clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
  clang-tools-extra/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
  clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
  clang-tools-extra/test/clang-tidy/abseil-time-subtraction.cpp
  clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp

Index: clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
+++ clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
 
 using int64_t = long long;
 
Index: clang-tools-extra/test/clang-tidy/abseil-time-subtraction.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/abseil-time-subtraction.cpp
+++ clang-tools-extra/test/clang-tidy/abseil-time-subtraction.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s abseil-time-subtraction %t -- -- -I %S/Inputs
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s abseil-time-subtraction %t -- -- -I %S/Inputs
 
 #include "absl/time/time.h"
 
Index: clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
+++ clang-tools-extra/test/clang-tidy/abseil-faster-strsplit-delimiter.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s abseil-faster-strsplit-delimiter %t
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s abseil-faster-strsplit-delimiter %t
 
 namespace absl {
 
Index: clang-tools-extra/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
+++ clang-tools-extra/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs
 
 #include "absl/time/time.h"
 
Index: clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
+++ clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
@@ -17,7 +17,8 @@
 namespace tidy {
 namespace abseil {
 
-/// Finds deprecated uses of `absl::Duration` arithmetic operators and factories.
+/// Finds deprecated uses of `absl::Duration` arithmetic operators and
+/// factories.
 ///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/abseil-upgrade-duration-conversions.html
Index: clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
+++ clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
@@ -10,6 +10,8 @@
 #include "DurationRewriter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Specifiers.h"
 
 using namespace clang::ast_matchers;
 
@@ -34,13 +36,15 @@
   Finder->addMatcher(
       cxxOperatorCallExpr(
           argumentCountIs(2),
-          hasArgument(
-              0, expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))))),
+          hasArgument(0,
+                      expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))))
+                          .bind("arg0")),
           hasArgument(1, expr().bind("arg")),
           callee(functionDecl(
               hasParent(functionTemplateDecl()),
               unless(hasTemplateArgument(0, refersToType(builtinType()))),
-              hasAnyName("operator*=", "operator/=")))),
+              hasAnyName("operator*=", "operator/="))))
+          .bind("operator"),
       this);
 
   // Match expressions like `a.operator*=(b)` and `a.operator/=(b)` where `a`
@@ -52,7 +56,8 @@
               hasParent(functionTemplateDecl()),
               unless(hasTemplateArgument(0, refersToType(builtinType()))),
               hasAnyName("operator*=", "operator/="))),
-          argumentCountIs(1), hasArgument(0, expr().bind("arg"))),
+          argumentCountIs(1), hasArgument(0, expr().bind("arg")))
+          .bind("operator"),
       this);
 
   // Match expressions like `a * b`, `a / b`, `operator*(a, b)`, and
@@ -66,7 +71,8 @@
                argumentCountIs(2),
                hasArgument(0, expr(hasType(
                                   cxxRecordDecl(hasName("::absl::Duration"))))),
-               hasArgument(1, expr().bind("arg"))),
+               hasArgument(1, expr().bind("arg")))
+          .bind("operator"),
       this);
 
   // Match expressions like `a * b` and `operator*(a, b)` where `a` is not of a
@@ -77,8 +83,9 @@
                    unless(hasTemplateArgument(0, refersToType(builtinType()))),
                    hasName("::absl::operator*"))),
                argumentCountIs(2), hasArgument(0, expr().bind("arg")),
-               hasArgument(1, expr(hasType(cxxRecordDecl(
-                                  hasName("::absl::Duration")))))),
+               hasArgument(1, expr(hasType(
+                                  cxxRecordDecl(hasName("::absl::Duration"))))))
+          .bind("operator"),
       this);
 
   // For the factory functions, we match only the non-templated overloads that
@@ -103,8 +110,9 @@
                 has(implicitCastExpr(hasCastKind(CK_UserDefinedConversion)))),
           hasParent(callExpr(
               callee(functionDecl(DurationFactoryFunction(),
-                  unless(hasParent(functionTemplateDecl())))),
-              hasArgument(0, expr().bind("arg"))))),
+                                  unless(hasParent(functionTemplateDecl())))),
+              hasArgument(0, expr().bind("arg")))))
+          .bind("operator"),
       this);
 }
 
@@ -115,9 +123,12 @@
       "explicit cast instead";
 
   const auto *ArgExpr = Result.Nodes.getNodeAs<Expr>("arg");
-  SourceLocation Loc = ArgExpr->getBeginLoc();
 
-  if (!match(isInTemplateInstantiation(), *ArgExpr, *Result.Context).empty()) {
+  const auto *OperatorExpr = Result.Nodes.getNodeAs<Expr>("operator");
+
+  SourceLocation Loc = ArgExpr->getBeginLoc();
+  if (!match(isInTemplateInstantiation(), *OperatorExpr, *Result.Context)
+           .empty()) {
     if (MatchedTemplateLocations.count(Loc.getRawEncoding()) == 0) {
       // For each location matched in a template instantiation, we check if the
       // location can also be found in `MatchedTemplateLocations`. If it is not
@@ -126,6 +137,7 @@
       // probably required so we provide only a warning.
       diag(Loc, Message);
     }
+
     return;
   }
 
Index: clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp
+++ clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp
@@ -10,6 +10,7 @@
 #include "DurationRewriter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/FixIt.h"
 
 using namespace clang::ast_matchers;
@@ -29,33 +30,24 @@
 
 static bool isConstructorAssignment(const MatchFinder::MatchResult &Result,
                                     const Expr *Node) {
-  return selectFirst<const Expr>(
-             "e", match(expr(hasParent(materializeTemporaryExpr(hasParent(
-                                 cxxConstructExpr(hasParent(exprWithCleanups(
-                                     hasParent(varDecl()))))))))
-                            .bind("e"),
-                        *Node, *Result.Context)) != nullptr;
+  return selectFirst<const Expr>("e",
+                                 match(expr(hasAncestor(varDecl())).bind("e"),
+                                       *Node, *Result.Context)) != nullptr;
 }
 
 static bool isArgument(const MatchFinder::MatchResult &Result,
                        const Expr *Node) {
   return selectFirst<const Expr>(
-             "e",
-             match(expr(hasParent(
-                            materializeTemporaryExpr(hasParent(cxxConstructExpr(
-                                hasParent(callExpr()),
-                                unless(hasParent(cxxOperatorCallExpr())))))))
-                       .bind("e"),
-                   *Node, *Result.Context)) != nullptr;
+             "e", match(expr(hasAncestor(callExpr()),
+                             unless(hasAncestor(cxxOperatorCallExpr())))
+                            .bind("e"),
+                        *Node, *Result.Context)) != nullptr;
 }
 
 static bool isReturn(const MatchFinder::MatchResult &Result, const Expr *Node) {
   return selectFirst<const Expr>(
-             "e", match(expr(hasParent(materializeTemporaryExpr(hasParent(
-                                 cxxConstructExpr(hasParent(exprWithCleanups(
-                                     hasParent(returnStmt()))))))))
-                            .bind("e"),
-                        *Node, *Result.Context)) != nullptr;
+             "e", match(expr(hasAncestor(returnStmt())).bind("e"), *Node,
+                        *Result.Context)) != nullptr;
 }
 
 static bool parensRequired(const MatchFinder::MatchResult &Result,
@@ -106,7 +98,6 @@
     Finder->addMatcher(OperandMatcher, this);
   }
 }
-
 void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
   std::string InverseName =
Index: clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
+++ clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
@@ -9,6 +9,7 @@
 #include "FasterStrsplitDelimiterCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 
 using namespace clang::ast_matchers;
 
@@ -48,7 +49,8 @@
   if (Result == R"("'")")
     return std::string(R"('\'')");
 
-  assert(Result.size() == 3 || (Result.size() == 4 && Result.substr(0, 2) == "\"\\"));
+  assert(Result.size() == 3 ||
+         (Result.size() == 4 && Result.substr(0, 2) == "\"\\"));
 
   // Now replace the " with '.
   auto Pos = Result.find_first_of('"');
@@ -75,11 +77,16 @@
   // Binds to a string_view (either absl or std) that was passed by value and
   // contructed from string literal.
   auto StringViewArg =
-      copyConstructExprWithArg("::absl::string_view", SingleChar);
+      anyOf(copyConstructExprWithArg("::absl::string_view", SingleChar),
+            constructExprWithArg("::absl::string_view", SingleChar));
 
   auto ByAnyCharArg =
-      expr(copyConstructExprWithArg("::absl::ByAnyChar", StringViewArg))
-          .bind("ByAnyChar");
+      anyOf(expr(copyConstructExprWithArg("::absl::ByAnyChar", StringViewArg))
+                .bind("ByAnyChar"),
+            expr(hasDescendant(cxxConstructExpr(
+                     hasType(recordDecl(hasName("::absl::ByAnyChar"))),
+                     hasArgument(0, ignoringParenCasts(StringViewArg)))))
+                .bind("ByAnyChar"));
 
   // Find uses of absl::StrSplit(..., "x") and absl::StrSplit(...,
   // absl::ByAnyChar("x")) to transform them into absl::StrSplit(..., 'x').
@@ -110,6 +117,7 @@
   llvm::Optional<std::string> Replacement = makeCharacterLiteral(Literal);
   if (!Replacement)
     return;
+
   SourceRange Range = Literal->getSourceRange();
 
   if (const auto *ByAnyChar = Result.Nodes.getNodeAs<Expr>("ByAnyChar"))
Index: clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
+++ clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
@@ -11,6 +11,7 @@
 #include "DurationRewriter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/FixIt.h"
 
 using namespace clang::ast_matchers;
@@ -19,6 +20,11 @@
 namespace tidy {
 namespace abseil {
 
+ast_matchers::internal::Matcher<Expr>
+elidable(ast_matchers::internal::Matcher<Expr> InnerMatcher) {
+  return anyOf(cxxConstructExpr(hasArgument(0, InnerMatcher)), InnerMatcher);
+}
+
 void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) {
   for (const auto &Scale : {"Hours", "Minutes", "Seconds", "Milliseconds",
                             "Microseconds", "Nanoseconds"}) {
@@ -30,10 +36,10 @@
 
     // Matcher which matches the current scale's factory with a `1` argument,
     // e.g. `absl::Seconds(1)`.
-    auto factory_matcher = cxxConstructExpr(hasArgument(
-        0,
+
+    auto factory_matcher = elidable(
         callExpr(callee(functionDecl(hasName(DurationFactory))),
-                 hasArgument(0, ignoringImpCasts(integerLiteral(equals(1)))))));
+                 hasArgument(0, ignoringImpCasts(integerLiteral(equals(1))))));
 
     // Matcher which matches either inverse function and binds its argument,
     // e.g. `absl::ToDoubleSeconds(dur)`.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to