[Clang-tidy]: Fix modernize-avoid-bind erroneous scope resolution.
authorHaojian Wu <hokein@google.com>
Thu, 20 Oct 2016 11:32:47 +0000 (11:32 +0000)
committerHaojian Wu <hokein@google.com>
Thu, 20 Oct 2016 11:32:47 +0000 (11:32 +0000)
Hello, i would like to suggest a fix for one of the checks in clang-tidy and i should hope this one is the correct mailing list.
The check is modernize-avoid-bind.

Consider the following:

  void bar(int x, int y);

  namespace N {
    void bar(int x, int y);
  }

  void foo(){
    auto Test = std::bind(N::bar,1,1);
  }

clang-tidy’s modernize-avoid-bind check suggests writing:

  void foo(){
    auto Test =[] {return bar(1,1);};
  }

instead of:

  void foo(){
    auto Test = [] {return N::bar(1,1);};
  }

So clang-tidy has proposed an incorrect Fix.

Patch by IdrissRio!

Reviewers: alexfh, hokein, aaron.ballman

Subscriber: cfe-commits
llvm-svn: 284719

clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp
clang-tools-extra/test/clang-tidy/modernize-avoid-bind.cpp

index c7c51a2..2b9a482 100644 (file)
@@ -108,8 +108,9 @@ void AvoidBindCheck::registerMatchers(MatchFinder *Finder) {
     return;
 
   Finder->addMatcher(
-      callExpr(callee(namedDecl(hasName("::std::bind"))),
-               hasArgument(0, declRefExpr(to(functionDecl().bind("f")))))
+      callExpr(
+          callee(namedDecl(hasName("::std::bind"))),
+          hasArgument(0, declRefExpr(to(functionDecl().bind("f"))).bind("ref")))
           .bind("bind"),
       this);
 }
@@ -148,14 +149,17 @@ void AvoidBindCheck::check(const MatchFinder::MatchResult &Result) {
 
   bool HasCapturedArgument = llvm::any_of(
       Args, [](const BindArgument &B) { return B.Kind == BK_Other; });
-
+  const auto *Ref = Result.Nodes.getNodeAs<DeclRefExpr>("ref");
   Stream << "[" << (HasCapturedArgument ? "=" : "") << "]";
   addPlaceholderArgs(Args, Stream);
-  Stream << " { return " << F->getName() << "(";
+  Stream << " { return ";
+  Ref->printPretty(Stream, nullptr, Result.Context->getPrintingPolicy());
+  Stream<< "(";
   addFunctionCallArgs(Args, Stream);
   Stream << "); };";
 
-  Diag << FixItHint::CreateReplacement(MatchedDecl->getSourceRange(), Stream.str());
+  Diag << FixItHint::CreateReplacement(MatchedDecl->getSourceRange(),
+                                       Stream.str());
 }
 
 } // namespace modernize
index 40b5fc2..1c78b9e 100644 (file)
@@ -68,3 +68,12 @@ void m() {
   // CHECK-FIXES: auto clj = std::bind(add, 1, add(2, 5));
 }
 
+namespace C {
+  int add(int x, int y){ return x + y; }
+}
+
+void n() {
+  auto clj = std::bind(C::add, 1, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: auto clj = [] { return C::add(1, 1); };
+}