[clang-tools-extra] r347537 - [clang-tidy] Don't generate incorrect fixes for class with deleted copy constructor in smart_ptr check.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 26 01:33:08 PST 2018


Author: hokein
Date: Mon Nov 26 01:33:08 2018
New Revision: 347537

URL: http://llvm.org/viewvc/llvm-project?rev=347537&view=rev
Log:
[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

Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.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=347537&r1=347536&r2=347537&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Mon Nov 26 01:33:08 2018
@@ -387,6 +387,19 @@ bool MakeSmartPtrCheck::replaceNew(Diagn
       //   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());

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=347537&r1=347536&r2=347537&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 Nov 26 01:33:08 2018
@@ -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




More information about the cfe-commits mailing list