forked from OSchip/llvm-project
[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 llvm-svn: 280180
This commit is contained in:
parent
3f8f7840bf
commit
d57be707b8
|
@ -29,13 +29,19 @@ void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||||
if (!getLangOpts().CPlusPlus11)
|
if (!getLangOpts().CPlusPlus11)
|
||||||
return;
|
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(
|
Finder->addMatcher(
|
||||||
cxxBindTemporaryExpr(has(ignoringParenImpCasts(
|
cxxBindTemporaryExpr(has(ignoringParenImpCasts(
|
||||||
cxxConstructExpr(
|
cxxConstructExpr(
|
||||||
hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
|
hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
|
||||||
hasArgument(0,
|
hasArgument(0,
|
||||||
cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
|
cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
|
||||||
equalsBoundNode(PointerType))))))
|
equalsBoundNode(PointerType))))),
|
||||||
|
CanCallCtor)
|
||||||
.bind(NewExpression)))
|
.bind(NewExpression)))
|
||||||
.bind(ConstructorCall)))),
|
.bind(ConstructorCall)))),
|
||||||
this);
|
this);
|
||||||
|
|
|
@ -97,6 +97,14 @@ Improvements to clang-tidy
|
||||||
Flags function parameters of a pointer type that could be changed to point to
|
Flags function parameters of a pointer type that could be changed to point to
|
||||||
a constant type instead.
|
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
|
Improvements to include-fixer
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,38 @@ void basic() {
|
||||||
std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
|
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) {
|
void initialization(int T, Base b) {
|
||||||
// Test different kinds of initialization of the pointee.
|
// Test different kinds of initialization of the pointee.
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,38 @@ void basic() {
|
||||||
std::unique_ptr<int> Placement = std::unique_ptr<int>(new (PInt) int{3});
|
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) {
|
void initialization(int T, Base b) {
|
||||||
// Test different kinds of initialization of the pointee.
|
// Test different kinds of initialization of the pointee.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue