[clang-tools-extra] r310035 - [clang-tidy] Support initializer-list constructor cases in modernize-make-unique.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 4 01:07:05 PDT 2017
Author: hokein
Date: Fri Aug 4 01:07:05 2017
New Revision: 310035
URL: http://llvm.org/viewvc/llvm-project?rev=310035&view=rev
Log:
[clang-tidy] Support initializer-list constructor cases in modernize-make-unique.
Reviewers: alexfh
Reviewed By: alexfh
Subscribers: malcolm.parsons, JDevlieghere, xazax.hun, cfe-commits
Differential Revision: https://reviews.llvm.org/D36016
Added:
clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h
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=310035&r1=310034&r2=310035&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Fri Aug 4 01:07:05 2017
@@ -242,16 +242,33 @@ void MakeSmartPtrCheck::replaceNew(Diagn
// Range of the substring that we do not want to remove.
SourceRange InitRange;
if (const auto *NewConstruct = New->getConstructExpr()) {
- // Direct initialization with initialization list.
- // struct S { S(int x) {} };
- // smart_ptr<S>(new S{5});
- // The arguments in the initialization list are going to be forwarded to
- // the constructor, so this has to be replaced with:
- // struct S { S(int x) {} };
- // std::make_smart_ptr<S>(5);
- InitRange = SourceRange(
- NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
- NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
+ if (NewConstruct->isStdInitListInitialization()) {
+ // Direct Initialization with the initializer-list constructor.
+ // struct S { S(std::initializer_list<T>); };
+ // smart_ptr<S>(new S{1, 2, 3});
+ // smart_ptr<S>(new S{}); // use initializer-list consturctor
+ // The brace has to be kept, so this has to be replaced with:
+ // std::make_smart_ptr<S>({1, 2, 3});
+ // std::make_smart_ptr<S>({});
+ unsigned NumArgs = NewConstruct->getNumArgs();
+ if (NumArgs == 0) {
+ return;
+ }
+ InitRange = SourceRange(NewConstruct->getArg(0)->getLocStart(),
+ NewConstruct->getArg(NumArgs - 1)->getLocEnd());
+ } else {
+ // Direct initialization with ordinary constructors.
+ // struct S { S(int x); S(); };
+ // smart_ptr<S>(new S{5});
+ // smart_ptr<S>(new S{}); // use default constructor
+ // The arguments in the initialization list are going to be forwarded to
+ // the constructor, so this has to be replaced with:
+ // std::make_smart_ptr<S>(5);
+ // std::make_smart_ptr<S>();
+ InitRange = SourceRange(
+ NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
+ NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
+ }
} else {
// Aggregate initialization.
// smart_ptr<Pair>(new Pair{first, second});
Added: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h?rev=310035&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h (added)
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/initializer_list.h Fri Aug 4 01:07:05 2017
@@ -0,0 +1,25 @@
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+
+template <class _E> class initializer_list {
+ const _E *__begin_;
+ size_t __size_;
+
+ initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {}
+
+public:
+ typedef _E value_type;
+ typedef const _E &reference;
+ typedef const _E &const_reference;
+ typedef size_t size_type;
+
+ typedef const _E *iterator;
+ typedef const _E *const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const { return __size_; }
+ const _E *begin() const { return __begin_; }
+ const _E *end() const { return __begin_ + __size_; }
+};
+} // namespace std
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=310035&r1=310034&r2=310035&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 Fri Aug 4 01:07:05 2017
@@ -2,6 +2,7 @@
// RUN: -I%S/Inputs/modernize-smart-ptr
#include "unique_ptr.h"
+#include "initializer_list.h"
// CHECK-FIXES: #include <memory>
struct Base {
@@ -26,6 +27,22 @@ struct DPair {
struct Empty {};
+struct E {
+ E(std::initializer_list<int>);
+ E();
+};
+
+struct F {
+ F(std::initializer_list<int>);
+ F();
+ int a;
+};
+
+struct G {
+ G(std::initializer_list<int>);
+ G(int);
+};
+
namespace {
class Foo {};
} // namespace
@@ -225,6 +242,57 @@ 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{});
+ // 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
+ // CHECK-FIXES: std::unique_ptr<E> PE1 = std::make_unique<E>();
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<E> PE2 = std::unique_ptr<E>(new E{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<E> PE2 = std::make_unique<E>({1, 2});
+
+ // Initialization with default constructor.
+ std::unique_ptr<F> PF1 = std::unique_ptr<F>(new F());
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF1 = std::make_unique<F>();
+
+ // Initialization with default constructor.
+ std::unique_ptr<F> PF2 = std::unique_ptr<F>(new F{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF2 = std::make_unique<F>();
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF3 = std::unique_ptr<F>(new F{1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF3 = std::make_unique<F>({1});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF4 = std::unique_ptr<F>(new F{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF4 = std::make_unique<F>({1, 2});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<F> PF5 = std::unique_ptr<F>(new F({1, 2}));
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<F> PF5 = std::make_unique<F>({1, 2});
+
+ // Initialization with the initializer-list constructor as the default
+ // constructor is not present.
+ std::unique_ptr<G> PG1 = std::unique_ptr<G>(new G{});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG1 = std::make_unique<G>({});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<G> PG2 = std::unique_ptr<G>(new G{1});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG2 = std::make_unique<G>({1});
+
+ // Initialization with the initializer-list constructor.
+ std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});
+ // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+ // CHECK-FIXES: std::unique_ptr<G> PG3 = std::make_unique<G>({1, 2});
+
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>();
More information about the cfe-commits
mailing list