[clang-tools-extra] r285589 - [clang-tidy] Enhance modernize-make-unique to handle unique_ptr.reset()

Malcolm Parsons via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 31 08:48:02 PDT 2016


Author: malcolm.parsons
Date: Mon Oct 31 10:48:01 2016
New Revision: 285589

URL: http://llvm.org/viewvc/llvm-project?rev=285589&view=rev
Log:
[clang-tidy] Enhance modernize-make-unique to handle unique_ptr.reset()

Summary:
Avoid naked new in unique_ptr.reset() by using make_unique

Fixes http://llvm.org/PR27383

Reviewers: alexfh, aaron.ballman

Subscribers: Prazek, cfe-commits

Differential Revision: https://reviews.llvm.org/D25898

Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst
    clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp
    clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp

Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Mon Oct 31 10:48:01 2016
@@ -18,6 +18,7 @@ namespace modernize {
 
 const char MakeSmartPtrCheck::PointerType[] = "pointerType";
 const char MakeSmartPtrCheck::ConstructorCall[] = "constructorCall";
+const char MakeSmartPtrCheck::ResetCall[] = "resetCall";
 const char MakeSmartPtrCheck::NewExpression[] = "newExpression";
 
 MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
@@ -31,8 +32,8 @@ void MakeSmartPtrCheck::registerMatchers
 
   // Calling make_smart_ptr from within a member function of a type with a
   // private or protected constructor would be ill-formed.
-  auto CanCallCtor = unless(has(ignoringImpCasts(cxxConstructExpr(
-      hasDeclaration(decl(unless(isPublic())))))));
+  auto CanCallCtor = unless(has(ignoringImpCasts(
+      cxxConstructExpr(hasDeclaration(decl(unless(isPublic())))))));
 
   Finder->addMatcher(
       cxxBindTemporaryExpr(has(ignoringParenImpCasts(
@@ -45,6 +46,14 @@ void MakeSmartPtrCheck::registerMatchers
                               .bind(NewExpression)))
               .bind(ConstructorCall)))),
       this);
+
+  Finder->addMatcher(
+      cxxMemberCallExpr(
+          thisPointerType(getSmartPointerTypeMatcher()),
+          callee(cxxMethodDecl(hasName("reset"))),
+          hasArgument(0, cxxNewExpr(CanCallCtor).bind(NewExpression)))
+          .bind(ResetCall),
+      this);
 }
 
 void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) {
@@ -55,12 +64,23 @@ void MakeSmartPtrCheck::check(const Matc
   SourceManager &SM = *Result.SourceManager;
   const auto *Construct =
       Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall);
+  const auto *Reset = Result.Nodes.getNodeAs<CXXMemberCallExpr>(ResetCall);
   const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType);
   const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression);
 
   if (New->getNumPlacementArgs() != 0)
     return;
 
+  if (Construct)
+    checkConstruct(SM, Construct, Type, New);
+  else if (Reset)
+    checkReset(SM, Reset, New);
+}
+
+void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
+                                       const CXXConstructExpr *Construct,
+                                       const QualType *Type,
+                                       const CXXNewExpr *New) {
   SourceLocation ConstructCallStart = Construct->getExprLoc();
 
   bool Invalid = false;
@@ -105,6 +125,36 @@ void MakeSmartPtrCheck::check(const Matc
         ")");
   }
 
+  replaceNew(Diag, New);
+}
+
+void MakeSmartPtrCheck::checkReset(SourceManager &SM,
+                                   const CXXMemberCallExpr *Reset,
+                                   const CXXNewExpr *New) {
+  const auto *Expr = cast<MemberExpr>(Reset->getCallee());
+  SourceLocation OperatorLoc = Expr->getOperatorLoc();
+  SourceLocation ResetCallStart = Reset->getExprLoc();
+  SourceLocation ExprStart = Expr->getLocStart();
+  SourceLocation ExprEnd =
+      Lexer::getLocForEndOfToken(Expr->getLocEnd(), 0, SM, getLangOpts());
+
+  auto Diag = diag(ResetCallStart, "use %0 instead")
+              << makeSmartPtrFunctionName;
+
+  Diag << FixItHint::CreateReplacement(
+      CharSourceRange::getCharRange(OperatorLoc, ExprEnd),
+      (llvm::Twine(" = ") + makeSmartPtrFunctionName + "<" +
+       New->getAllocatedType().getAsString(getLangOpts()) + ">")
+          .str());
+
+  if (Expr->isArrow())
+    Diag << FixItHint::CreateInsertion(ExprStart, "*");
+
+  replaceNew(Diag, New);
+}
+
+void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
+                                   const CXXNewExpr *New) {
   SourceLocation NewStart = New->getSourceRange().getBegin();
   SourceLocation NewEnd = New->getSourceRange().getEnd();
   switch (New->getInitializationStyle()) {

Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h Mon Oct 31 10:48:01 2016
@@ -39,10 +39,17 @@ protected:
 
   static const char PointerType[];
   static const char ConstructorCall[];
+  static const char ResetCall[];
   static const char NewExpression[];
 
 private:
   std::string makeSmartPtrFunctionName;
+
+  void checkConstruct(SourceManager &SM, const CXXConstructExpr *Construct,
+                      const QualType *Type, const CXXNewExpr *New);
+  void checkReset(SourceManager &SM, const CXXMemberCallExpr *Member,
+                  const CXXNewExpr *New);
+  void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New);
 };
 
 } // namespace modernize

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Mon Oct 31 10:48:01 2016
@@ -81,6 +81,12 @@ Improvements to clang-tidy
   Warns if an object is used after it has been moved, without an intervening
   reinitialization.
 
+- `modernize-make-unique
+  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-unique.html>`_
+  and `modernize-make-shared
+  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-shared.html>`_
+  now handle calls to the smart pointer's reset method.
+
 - The `modernize-use-auto
   <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-auto.html>`_ check
   now warns about variable declarations that are initialized with a cast.

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst Mon Oct 31 10:48:01 2016
@@ -14,3 +14,14 @@ to ``std::make_shared``.
   // becomes
 
   auto my_ptr = std::make_shared<MyPair>(1, 2);
+
+This check also finds calls to ``std::shared_ptr::reset()`` with a ``new``
+expression, and replaces it with a call to ``std::make_shared``.
+
+.. code-block:: c++
+
+  my_ptr.reset(new MyPair(1, 2));
+
+  // becomes
+
+  my_ptr = std::make_shared<MyPair>(1, 2);

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst Mon Oct 31 10:48:01 2016
@@ -14,3 +14,14 @@ to ``std::make_unique``, introduced in C
   // becomes
 
   auto my_ptr = std::make_unique<MyPair>(1, 2);
+
+This check also finds calls to ``std::unique_ptr::reset()`` with a ``new``
+expression, and replaces it with a call to ``std::make_unique``.
+
+.. code-block:: c++
+
+  my_ptr.reset(new MyPair(1, 2));
+
+  // becomes
+
+  my_ptr = std::make_unique<MyPair>(1, 2);

Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp Mon Oct 31 10:48:01 2016
@@ -5,6 +5,7 @@ namespace std {
 template <typename type>
 class shared_ptr {
 public:
+  shared_ptr();
   shared_ptr(type *ptr);
   shared_ptr(const shared_ptr<type> &t) {}
   shared_ptr(shared_ptr<type> &&t) {}
@@ -14,6 +15,9 @@ public:
   type *release();
   void reset();
   void reset(type *pt);
+  shared_ptr &operator=(shared_ptr &&);
+  template <typename T>
+  shared_ptr &operator=(shared_ptr<T> &&);
 
 private:
   type *ptr;
@@ -60,11 +64,27 @@ void basic() {
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
   // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();
 
+  P1.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P1 = std::make_shared<int>();
+
+  P1 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P1 = std::make_shared<int>();
+
   // Without parenthesis.
   std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
   // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>();
 
+  P2.reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P2 = std::make_shared<int>();
+
+  P2 = std::shared_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P2 = std::make_shared<int>();
+
   // With auto.
   auto P3 = std::shared_ptr<int>(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
@@ -76,6 +96,10 @@ void basic() {
     shared_ptr<int> Q = shared_ptr<int>(new int());
     // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead
     // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();
+
+    Q = shared_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+    // CHECK-FIXES: Q = std::make_shared<int>();
   }
 
   std::shared_ptr<int> R(new int());
@@ -85,19 +109,36 @@ void basic() {
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
   // CHECK-FIXES: int T = g(std::make_shared<int>());
 
-  // Only replace if the type in the template is the same than the type returned
+  // Only replace if the type in the template is the same as the type returned
   // by the new operator.
   auto Pderived = std::shared_ptr<Base>(new Derived());
 
+  // OK to replace for reset and assign
+  Pderived.reset(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead
+  // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+  Pderived = std::shared_ptr<Derived>(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead
+  // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+  // FIXME: OK to replace if assigned to shared_ptr<Base>
+  Pderived = std::shared_ptr<Base>(new Derived());
+
+  // FIXME: OK to replace when auto is not used
+  std::shared_ptr<Base> PBase = std::shared_ptr<Base>(new Derived());
+
   // The pointer is returned by the function, nothing to do.
   std::shared_ptr<Base> RetPtr = getPointer();
 
   // This emulates std::move.
   std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);
 
-  // Placemenet arguments should not be removed.
+  // Placement arguments should not be removed.
   int *PInt = new int;
   std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
+  Placement.reset(new (PInt) int{3});
+  Placement = std::shared_ptr<int>(new (PInt) int{3});
 }
 
 // Calling make_smart_ptr from within a member function of a type with a
@@ -113,6 +154,8 @@ public:
     // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
     // CHECK-FIXES: auto callsPublic = std::make_shared<Private>();
     auto ptr = std::shared_ptr<Private>(new Private(42));
+    ptr.reset(new Private(42));
+    ptr = std::shared_ptr<Private>(new Private(42));
   }
 
   virtual ~Private();
@@ -129,6 +172,8 @@ public:
     // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
     // CHECK-FIXES: auto callsPublic = std::make_shared<Protected>(1, 2);
     auto ptr = std::shared_ptr<Protected>(new Protected);
+    ptr.reset(new Protected);
+    ptr = std::shared_ptr<Protected>(new Protected);
   }
 };
 
@@ -139,16 +184,25 @@ void initialization(int T, Base b) {
   std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
   // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);
+  PDir1.reset(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: PDir1 = std::make_shared<DPair>(1, T);
 
   // Direct initialization with braces.
   std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
   // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);
+  PDir2.reset(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: PDir2 = std::make_shared<DPair>(2, T);
 
   // Aggregate initialization.
   std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
   // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
+  PAggr.reset(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: std::make_shared<APair>(APair{T, 1});
 
   // Test different kinds of initialization of the pointee, when the shared_ptr
   // is initialized with braces.
@@ -229,4 +283,24 @@ void nesting() {
   auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead
   // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);
+  Nest.reset(new std::shared_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead
+  // CHECK-FIXES: Nest = std::make_shared<std::shared_ptr<int>>(new int);
+  Nest->reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: *Nest = std::make_shared<int>();
+}
+
+void reset() {
+  std::shared_ptr<int> P;
+  P.reset();
+  P.reset(nullptr);
+  P.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_shared instead
+  // CHECK-FIXES: P = std::make_shared<int>();
+
+  auto Q = &P;
+  Q->reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead
+  // CHECK-FIXES: *Q = std::make_shared<int>();
 }

Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=285589&r1=285588&r2=285589&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Mon Oct 31 10:48:01 2016
@@ -8,6 +8,7 @@ class default_delete {};
 template <typename type, typename Deleter = std::default_delete<type>>
 class unique_ptr {
 public:
+  unique_ptr();
   unique_ptr(type *ptr);
   unique_ptr(const unique_ptr<type> &t) = delete;
   unique_ptr(unique_ptr<type> &&t);
@@ -17,11 +18,13 @@ public:
   type *release();
   void reset();
   void reset(type *pt);
+  unique_ptr &operator=(unique_ptr &&);
+  template <typename T>
+  unique_ptr &operator=(unique_ptr<T> &&);
 
 private:
   type *ptr;
 };
-
 }
 
 struct Base {
@@ -46,7 +49,8 @@ struct DPair {
 
 struct Empty {};
 
-template<class T> using unique_ptr_ = std::unique_ptr<T>;
+template <class T>
+using unique_ptr_ = std::unique_ptr<T>;
 
 void *operator new(__SIZE_TYPE__ Count, void *Ptr);
 
@@ -63,11 +67,27 @@ void basic() {
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
   // CHECK-FIXES: std::unique_ptr<int> P1 = std::make_unique<int>();
 
+  P1.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P1 = std::make_unique<int>();
+
+  P1 = std::unique_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P1 = std::make_unique<int>();
+
   // Without parenthesis.
   std::unique_ptr<int> P2 = std::unique_ptr<int>(new int);
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
   // CHECK-FIXES: std::unique_ptr<int> P2 = std::make_unique<int>();
 
+  P2.reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P2 = std::make_unique<int>();
+
+  P2 = std::unique_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P2 = std::make_unique<int>();
+
   // With auto.
   auto P3 = std::unique_ptr<int>(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
@@ -79,6 +99,10 @@ void basic() {
     unique_ptr<int> Q = unique_ptr<int>(new int());
     // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_unique instead
     // CHECK-FIXES: unique_ptr<int> Q = std::make_unique<int>();
+
+    Q = unique_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+    // CHECK-FIXES: Q = std::make_unique<int>();
   }
 
   std::unique_ptr<int> R(new int());
@@ -88,19 +112,36 @@ void basic() {
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
   // CHECK-FIXES: int T = g(std::make_unique<int>());
 
-  // Only replace if the type in the template is the same than the type returned
+  // Only replace if the type in the template is the same as the type returned
   // by the new operator.
   auto Pderived = std::unique_ptr<Base>(new Derived());
 
+  // OK to replace for reset and assign
+  Pderived.reset(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_unique instead
+  // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+  Pderived = std::unique_ptr<Derived>(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_unique instead
+  // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+  // FIXME: OK to replace if assigned to unique_ptr<Base>
+  Pderived = std::unique_ptr<Base>(new Derived());
+
+  // FIXME: OK to replace when auto is not used
+  std::unique_ptr<Base> PBase = std::unique_ptr<Base>(new Derived());
+
   // The pointer is returned by the function, nothing to do.
   std::unique_ptr<Base> RetPtr = getPointer();
 
   // This emulates std::move.
-  std::unique_ptr<int> Move = static_cast<std::unique_ptr<int>&&>(P1);
+  std::unique_ptr<int> Move = static_cast<std::unique_ptr<int> &&>(P1);
 
-  // Placemenet arguments should not be removed.
+  // Placement arguments should not be removed.
   int *PInt = new int;
   std::unique_ptr<int> Placement = std::unique_ptr<int>(new (PInt) int{3});
+  Placement.reset(new (PInt) int{3});
+  Placement = std::unique_ptr<int>(new (PInt) int{3});
 }
 
 // Calling make_smart_ptr from within a member function of a type with a
@@ -116,6 +157,8 @@ public:
     // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
     // CHECK-FIXES: auto callsPublic = std::make_unique<Private>();
     auto ptr = std::unique_ptr<Private>(new Private(42));
+    ptr.reset(new Private(42));
+    ptr = std::unique_ptr<Private>(new Private(42));
   }
 
   virtual ~Private();
@@ -132,6 +175,8 @@ public:
     // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
     // CHECK-FIXES: auto callsPublic = std::make_unique<Protected>(1, 2);
     auto ptr = std::unique_ptr<Protected>(new Protected);
+    ptr.reset(new Protected);
+    ptr = std::unique_ptr<Protected>(new Protected);
   }
 };
 
@@ -142,17 +187,25 @@ void initialization(int T, Base b) {
   std::unique_ptr<DPair> PDir1 = std::unique_ptr<DPair>(new DPair(1, T));
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
   // CHECK-FIXES: std::unique_ptr<DPair> PDir1 = std::make_unique<DPair>(1, T);
+  PDir1.reset(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: PDir1 = std::make_unique<DPair>(1, T);
 
   // Direct initialization with braces.
   std::unique_ptr<DPair> PDir2 = std::unique_ptr<DPair>(new DPair{2, T});
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
   // CHECK-FIXES: std::unique_ptr<DPair> PDir2 = std::make_unique<DPair>(2, T);
+  PDir2.reset(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: PDir2 = std::make_unique<DPair>(2, T);
 
   // Aggregate initialization.
   std::unique_ptr<APair> PAggr = std::unique_ptr<APair>(new APair{T, 1});
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
   // CHECK-FIXES: std::unique_ptr<APair> PAggr = std::make_unique<APair>(APair{T, 1});
-
+  PAggr.reset(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: std::make_unique<APair>(APair{T, 1});
 
   // Test different kinds of initialization of the pointee, when the unique_ptr
   // is initialized with braces.
@@ -172,7 +225,6 @@ void initialization(int T, Base b) {
   // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
   // CHECK-FIXES: std::unique_ptr<APair> PAggr2 = std::make_unique<APair>(APair{T, 2});
 
-
   // Direct initialization with parenthesis, without arguments.
   std::unique_ptr<DPair> PDir5 = std::unique_ptr<DPair>(new DPair());
   // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
@@ -204,13 +256,13 @@ void aliases() {
   // We use 'Base' instead of 'struct Base'.
   typedef std::unique_ptr<Base> BasePtr;
   BasePtr StructType = BasePtr(new Base);
-  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
-  // CHECK-FIXES: BasePtr StructType = std::make_unique<Base>();
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+// CHECK-FIXES: BasePtr StructType = std::make_unique<Base>();
 
 #define PTR unique_ptr<int>
   std::unique_ptr<int> Macro = std::PTR(new int);
-  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
-  // CHECK-FIXES: std::unique_ptr<int> Macro = std::make_unique<int>();
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
+// CHECK-FIXES: std::unique_ptr<int> Macro = std::make_unique<int>();
 #undef PTR
 
   std::unique_ptr<int> Using = unique_ptr_<int>(new int);
@@ -219,6 +271,7 @@ void aliases() {
 }
 
 void whitespaces() {
+  // clang-format off
   auto Space = std::unique_ptr <int>(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_unique instead
   // CHECK-FIXES: auto Space = std::make_unique<int>();
@@ -226,10 +279,31 @@ void whitespaces() {
   auto Spaces = std  ::    unique_ptr  <int>(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
   // CHECK-FIXES: auto Spaces = std::make_unique<int>();
+  // clang-format on
 }
 
 void nesting() {
   auto Nest = std::unique_ptr<std::unique_ptr<int>>(new std::unique_ptr<int>(new int));
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead
   // CHECK-FIXES: auto Nest = std::make_unique<std::unique_ptr<int>>(new int);
+  Nest.reset(new std::unique_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead
+  // CHECK-FIXES: Nest = std::make_unique<std::unique_ptr<int>>(new int);
+  Nest->reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: *Nest = std::make_unique<int>();
+}
+
+void reset() {
+  std::unique_ptr<int> P;
+  P.reset();
+  P.reset(nullptr);
+  P.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_unique instead
+  // CHECK-FIXES: P = std::make_unique<int>();
+
+  auto Q = &P;
+  Q->reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead
+  // CHECK-FIXES: *Q = std::make_unique<int>();
 }




More information about the cfe-commits mailing list