summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2018-11-26 09:33:08 +0000
committerHaojian Wu <hokein@google.com>2018-11-26 09:33:08 +0000
commitdbfa9c3e0a34807489d31fca7dac3de5c1e0446d (patch)
tree67e7f03466342853815abca7880de188e643d043
parent717412b5f9016555241b134833f9d6297e3fac07 (diff)
downloadbcm5719-llvm-dbfa9c3e0a34807489d31fca7dac3de5c1e0446d.tar.gz
bcm5719-llvm-dbfa9c3e0a34807489d31fca7dac3de5c1e0446d.zip
[clang-tidy] Don't generate incorrect fixes for class with deleted copy constructor in smart_ptr check.
Summary: The fix for aggregate initialization (`std::make_unique<Foo>(Foo {1, 2})` needs to see Foo copy constructor, otherwise we will have a compiler error. So we only emit the check warning. Reviewers: JonasToth, aaron.ballman Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D54745 llvm-svn: 347537
-rw-r--r--clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp13
-rw-r--r--clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp59
2 files changed, 72 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index 54fc567a489..c8d66cadd6d 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -387,6 +387,19 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
// smart_ptr<Pair>(new Pair{first, second});
// Has to be replaced with:
// smart_ptr<Pair>(Pair{first, second});
+ //
+ // The fix (std::make_unique) needs to see copy/move constructor of
+ // Pair. If we found any invisible or deleted copy/move constructor, we
+ // stop generating fixes -- as the C++ rule is complicated and we are less
+ // certain about the correct fixes.
+ if (const CXXRecordDecl *RD = New->getType()->getPointeeCXXRecordDecl()) {
+ if (llvm::find_if(RD->ctors(), [](const CXXConstructorDecl *Ctor) {
+ return Ctor->isCopyOrMoveConstructor() &&
+ (Ctor->isDeleted() || Ctor->getAccess() == AS_private);
+ }) != RD->ctor_end()) {
+ return false;
+ }
+ }
InitRange = SourceRange(
New->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(),
New->getInitializer()->getSourceRange().getEnd());
diff --git a/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp b/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
index 57298f6f6a4..f3071f3aac5 100644
--- a/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
+++ b/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
@@ -32,6 +32,38 @@ struct MyVector {
struct Empty {};
+struct NoCopyMoveCtor {
+ NoCopyMoveCtor(const NoCopyMoveCtor &) = delete; // implies move ctor is deleted
+};
+
+struct NoCopyMoveCtorVisible {
+private:
+ NoCopyMoveCtorVisible(const NoCopyMoveCtorVisible&) = default;
+ NoCopyMoveCtorVisible(NoCopyMoveCtorVisible&&) = default;
+};
+
+struct OnlyMoveCtor {
+ OnlyMoveCtor() = default;
+ OnlyMoveCtor(OnlyMoveCtor&&) = default;
+ OnlyMoveCtor(const OnlyMoveCtor &) = delete;
+};
+
+struct OnlyCopyCtor {
+ OnlyCopyCtor(const OnlyCopyCtor&) = default;
+ OnlyCopyCtor(OnlyCopyCtor&&) = delete;
+};
+
+struct OnlyCopyCtorVisible {
+ OnlyCopyCtorVisible(const OnlyCopyCtorVisible &) = default;
+
+private:
+ OnlyCopyCtorVisible(OnlyCopyCtorVisible &&) = default;
+};
+
+struct ImplicitDeletedCopyCtor {
+ const OnlyMoveCtor ctor;
+};
+
struct E {
E(std::initializer_list<int>);
E();
@@ -274,6 +306,33 @@ void initialization(int T, Base b) {
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
// CHECK-FIXES: std::unique_ptr<Empty> PEmpty = std::make_unique<Empty>(Empty{});
+ // No fixes for classes with deleted copy&move constructors.
+ auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+
+ auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+
+ auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+
+ // Fix for classes with classes with move constructor.
+ auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+
+ // Fix for classes with classes with move constructor.
+ auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use std::make_unique instead
+ // CHECK-FIXES: auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+
+ auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+ // CHECK-FIXES: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+
// Initialization with default constructor.
std::unique_ptr<E> PE1 = std::unique_ptr<E>(new E{});
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
OpenPOWER on IntegriCloud