Author: prazek Date: Tue Aug 30 19:06:55 2016 New Revision: 280180 URL: http://llvm.org/viewvc/llvm-project?rev=280180&view=rev Log: [clang-tidy] modernize-make-{smart_ptr} private ctor bugfix
Summary: Bugfix for 27321. When the constructor of stored pointer type is private then it is invalid to change it to make_shared or make_unique. Reviewers: alexfh, aaron.ballman, hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D23343 Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/trunk/docs/ReleaseNotes.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=280180&r1=280179&r2=280180&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Tue Aug 30 19:06:55 2016 @@ -29,13 +29,19 @@ void MakeSmartPtrCheck::registerMatchers if (!getLangOpts().CPlusPlus11) return; + // 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()))))))); + Finder->addMatcher( cxxBindTemporaryExpr(has(ignoringParenImpCasts( cxxConstructExpr( hasType(getSmartPointerTypeMatcher()), argumentCountIs(1), hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( - equalsBoundNode(PointerType)))))) + equalsBoundNode(PointerType))))), + CanCallCtor) .bind(NewExpression))) .bind(ConstructorCall)))), this); Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=280180&r1=280179&r2=280180&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Tue Aug 30 19:06:55 2016 @@ -97,6 +97,14 @@ Improvements to clang-tidy Flags function parameters of a pointer type that could be changed to point to a constant type instead. +Fixed bugs: +- `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>`_ + Calling ``make_{unique|shared}`` from within a member function of a type + with a private or protected constructor would be ill-formed. + Improvements to include-fixer ----------------------------- 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=280180&r1=280179&r2=280180&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 Tue Aug 30 19:06:55 2016 @@ -100,6 +100,38 @@ void basic() { std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3}); } +// Calling make_smart_ptr from within a member function of a type with a +// private or protected constructor would be ill-formed. +class Private { +private: + Private(int z) {} + +public: + Private() {} + void create() { + auto callsPublic = std::shared_ptr<Private>(new Private); + // 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)); + } + + virtual ~Private(); +}; + +class Protected { +protected: + Protected() {} + +public: + Protected(int, int) {} + void create() { + auto callsPublic = std::shared_ptr<Protected>(new Protected(1, 2)); + // 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); + } +}; + void initialization(int T, Base b) { // Test different kinds of initialization of the pointee. 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=280180&r1=280179&r2=280180&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 Tue Aug 30 19:06:55 2016 @@ -103,6 +103,38 @@ void basic() { std::unique_ptr<int> Placement = std::unique_ptr<int>(new (PInt) int{3}); } +// Calling make_smart_ptr from within a member function of a type with a +// private or protected constructor would be ill-formed. +class Private { +private: + Private(int z) {} + +public: + Private() {} + void create() { + auto callsPublic = std::unique_ptr<Private>(new Private); + // 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)); + } + + virtual ~Private(); +}; + +class Protected { +protected: + Protected() {} + +public: + Protected(int, int) {} + void create() { + auto callsPublic = std::unique_ptr<Protected>(new Protected(1, 2)); + // 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); + } +}; + void initialization(int T, Base b) { // Test different kinds of initialization of the pointee. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits