[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
This commit is contained in:
parent
717412b5f9
commit
dbfa9c3e0a
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue