[clang-tools-extra] r223460 - [clang-tidy] Add clang-tidy check for unique_ptr's reset+release -> move

Alexander Kornienko alexfh at google.com
Fri Dec 5 03:59:06 PST 2014


Author: alexfh
Date: Fri Dec  5 05:59:05 2014
New Revision: 223460

URL: http://llvm.org/viewvc/llvm-project?rev=223460&view=rev
Log:
[clang-tidy] Add clang-tidy check for unique_ptr's reset+release -> move

Replace x.reset(y.release()); with x = std::move(y);
If y is rvalue, replace with x = y; instead.

http://reviews.llvm.org/D6485

Patch by Alexey Sokolov!

Added:
    clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.cpp
    clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.h
    clang-tools-extra/trunk/test/clang-tidy/misc-uniqueptr-reset-release.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=223460&r1=223459&r2=223460&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Fri Dec  5 05:59:05 2014
@@ -7,6 +7,7 @@ add_clang_library(clangTidyMiscModule
   SwappedArgumentsCheck.cpp
   UndelegatedConstructor.cpp
   UnusedRAII.cpp
+  UniqueptrResetRelease.cpp
   UseOverride.cpp
 
   LINK_LIBS

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=223460&r1=223459&r2=223460&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Fri Dec  5 05:59:05 2014
@@ -15,6 +15,7 @@
 #include "SwappedArgumentsCheck.h"
 #include "UndelegatedConstructor.h"
 #include "UnusedRAII.h"
+#include "UniqueptrResetRelease.h"
 #include "UseOverride.h"
 
 namespace clang {
@@ -30,6 +31,8 @@ public:
         "misc-swapped-arguments");
     CheckFactories.registerCheck<UndelegatedConstructorCheck>(
         "misc-undelegated-constructor");
+    CheckFactories.registerCheck<UniqueptrResetRelease>(
+        "misc-uniqueptr-reset-release");
     CheckFactories.registerCheck<UnusedRAIICheck>("misc-unused-raii");
     CheckFactories.registerCheck<UseOverride>("misc-use-override");
   }

Added: clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.cpp?rev=223460&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.cpp Fri Dec  5 05:59:05 2014
@@ -0,0 +1,66 @@
+//===--- UniqueptrResetRelease.cpp - clang-tidy ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UniqueptrResetRelease.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void UniqueptrResetRelease::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      memberCallExpr(
+          on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
+          callee(methodDecl(hasName("reset"),
+                            ofClass(hasName("::std::unique_ptr")))),
+          has(memberCallExpr(
+              on(expr().bind("right")),
+              callee(memberExpr().bind("release_member")),
+              callee(methodDecl(hasName("release"),
+                                ofClass(hasName("::std::unique_ptr")))))))
+          .bind("reset_call"),
+      this);
+}
+
+void UniqueptrResetRelease::check(const MatchFinder::MatchResult &Result) {
+  const auto *ResetMember = Result.Nodes.getNodeAs<MemberExpr>("reset_member");
+  const auto *ReleaseMember =
+      Result.Nodes.getNodeAs<MemberExpr>("release_member");
+  const auto *Right = Result.Nodes.getNodeAs<Expr>("right");
+  const auto *Left = Result.Nodes.getNodeAs<Expr>("left");
+  const auto *ResetCall =
+      Result.Nodes.getNodeAs<CXXMemberCallExpr>("reset_call");
+
+  std::string LeftText = clang::Lexer::getSourceText(
+      CharSourceRange::getTokenRange(Left->getSourceRange()),
+      *Result.SourceManager, Result.Context->getLangOpts());
+  std::string RightText = clang::Lexer::getSourceText(
+      CharSourceRange::getTokenRange(Right->getSourceRange()),
+      *Result.SourceManager, Result.Context->getLangOpts());
+
+  if (ResetMember->isArrow())
+    LeftText = "*" + LeftText;
+  if (ReleaseMember->isArrow())
+    RightText = "*" + RightText;
+  // Even if x was rvalue, *x is not rvalue anymore.
+  if (!Right->isRValue() || ReleaseMember->isArrow())
+    RightText = "std::move(" + RightText + ")";
+  std::string NewText = LeftText + " = " + RightText;
+
+  diag(ResetMember->getExprLoc(),
+       "prefer ptr1 = std::move(ptr2) over ptr1.reset(ptr2.release())")
+      << FixItHint::CreateReplacement(
+          CharSourceRange::getTokenRange(ResetCall->getSourceRange()), NewText);
+}
+
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.h?rev=223460&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/UniqueptrResetRelease.h Fri Dec  5 05:59:05 2014
@@ -0,0 +1,38 @@
+//===--- UniqueptrResetRelease.h - clang-tidy -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNIQUEPTR_RESET_RELEASE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNIQUEPTR_RESET_RELEASE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// \brief Find and replace unique_ptr::reset(release()) with std::move
+///
+/// Example:
+///   std::unique_ptr<Foo> x, y;
+///   x.reset(y.release()); -> x = std::move(y);
+///
+/// If "y" is already rvalue, std::move is not added.
+/// "x" and "y" can also be std::unique_ptr<Foo>*.
+class UniqueptrResetRelease : public ClangTidyCheck {
+public:
+  UniqueptrResetRelease(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNIQUEPTR_RESET_RELEASE_H

Added: clang-tools-extra/trunk/test/clang-tidy/misc-uniqueptr-reset-release.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-uniqueptr-reset-release.cpp?rev=223460&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-uniqueptr-reset-release.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-uniqueptr-reset-release.cpp Fri Dec  5 05:59:05 2014
@@ -0,0 +1,48 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-uniqueptr-reset-release %t
+// REQUIRES: shell
+
+namespace std {
+template <typename T>
+struct unique_ptr {
+  unique_ptr<T>();
+  explicit unique_ptr<T>(T *);
+  template <typename U>
+  unique_ptr<T>(unique_ptr<U> &&);
+  void reset(T *);
+  T *release();
+};
+} // namespace std
+
+struct Foo {};
+struct Bar : Foo {};
+
+std::unique_ptr<Foo> Create();
+std::unique_ptr<Foo> &Look();
+std::unique_ptr<Foo> *Get();
+
+void f() {
+  std::unique_ptr<Foo> a, b;
+  std::unique_ptr<Bar> c;
+  std::unique_ptr<Foo> *x = &a;
+  std::unique_ptr<Foo> *y = &b;
+
+  a.reset(b.release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2) over ptr1.reset(ptr2.release()) [misc-uniqueptr-reset-release]
+  // CHECK-FIXES: a = std::move(b);
+  a.reset(c.release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: a = std::move(c);
+  a.reset(Create().release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: a = Create();
+  x->reset(y->release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: *x = std::move(*y);
+  Look().reset(Look().release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: Look() = std::move(Look());
+  Get()->reset(Get()->release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: *Get() = std::move(*Get());
+}
+





More information about the cfe-commits mailing list