Skip to content

Commit

Permalink
[clang-tidy] A follow-up fix of braced-init-list constructors in make…
Browse files Browse the repository at this point in the history
…-unique check.

Reviewers: alexfh

Reviewed By: alexfh

Subscribers: JDevlieghere, xazax.hun, cfe-commits

Differential Revision: https://reviews.llvm.org/D37066

llvm-svn: 311652
  • Loading branch information
hokein committed Aug 24, 2017
1 parent 15ea4eb commit 3f49594
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
16 changes: 14 additions & 2 deletions clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
Expand Up @@ -262,20 +262,32 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
break;
}
case CXXNewExpr::CallInit: {
// FIXME: Add fixes for constructors with initializer-list parameters.
// FIXME: Add fixes for constructors with parameters that can be created
// with a C++11 braced-init-list (e.g. std::vector, std::map).
// Unlike ordinal cases, braced list can not be deduced in
// std::make_smart_ptr, we need to specify the type explicitly in the fixes:
// struct S { S(std::initializer_list<int>, int); };
// struct S2 { S2(std::vector<int>); };
// smart_ptr<S>(new S({1, 2, 3}, 1)); // C++98 call-style initialization
// smart_ptr<S>(new S({}, 1));
// smart_ptr<S2>(new S2({1})); // implicit conversion:
// // std::initializer_list => std::vector
// The above samples have to be replaced with:
// std::make_smart_ptr<S>(std::initializer_list<int>({1, 2, 3}), 1);
// std::make_smart_ptr<S>(std::initializer_list<int>({}), 1);
// std::make_smart_ptr<S2>(std::vector<int>({1}));
if (const auto *CE = New->getConstructExpr()) {
for (const auto *Arg : CE->arguments()) {
if (llvm::isa<CXXStdInitializerListExpr>(Arg)) {
if (isa<CXXStdInitializerListExpr>(Arg)) {
return false;
}
// Check the implicit conversion from the std::initializer_list type to
// a class type.
if (const auto *ImplicitCE = dyn_cast<CXXConstructExpr>(Arg)) {
if (ImplicitCE->isStdInitListInitialization()) {
return false;
}
}
}
}
if (ArraySizeExpr.empty()) {
Expand Down
Expand Up @@ -22,4 +22,10 @@ template <class _E> class initializer_list {
const _E *begin() const { return __begin_; }
const _E *end() const { return __begin_ + __size_; }
};

template <class _E>
class vector {
public:
vector(initializer_list<_E> init);
};
} // namespace std
22 changes: 22 additions & 0 deletions clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp
Expand Up @@ -43,6 +43,14 @@ struct G {
G(int);
};

struct H {
H(std::vector<int>);
};

struct I {
I(G);
};

namespace {
class Foo {};
} // namespace
Expand Down Expand Up @@ -316,6 +324,20 @@ void initialization(int T, Base b) {
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
// CHECK-FIXES: std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});

std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
// CHECK-FIXES: std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
PH1.reset(new H({1, 2, 3}));
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
// CHECK-FIXES: PH1.reset(new H({1, 2, 3}));

std::unique_ptr<I> PI1 = std::unique_ptr<I>(new I(G({1, 2, 3})));
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
// CHECK-FIXES: std::unique_ptr<I> PI1 = std::make_unique<I>(G({1, 2, 3}));
PI1.reset(new I(G({1, 2, 3})));
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
// CHECK-FIXES: PI1 = std::make_unique<I>(G({1, 2, 3}));

std::unique_ptr<Foo> FF = std::unique_ptr<Foo>(new Foo());
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning:
// CHECK-FIXES: std::unique_ptr<Foo> FF = std::make_unique<Foo>();
Expand Down

0 comments on commit 3f49594

Please sign in to comment.