[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