[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