[PATCH] D32767: [clang-tidy] Fix PR32896: detect initializer lists in modernize-use-empalce

Jakub Kuderski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue May 2 15:57:22 PDT 2017


kuhar created this revision.
kuhar added a project: clang-tools-extra.
Herald added a subscriber: xazax.hun.

This patch fixes PR32896 <https://bugs.llvm.org/show_bug.cgi?id=32896>.

The problem was that modernize-use-emplace incorrectly removed changed push_back into emplace_back, removing explicit constructor call with initializer list parameter, resulting in compiler error after applying fixits.
modernize-use-emplace used to check if matched constructor had InitListExpr, but didn't check against CXXStdInitializerListExpr.

Eg.

  std::vector<std::vector<int>> v;
    v.push_back(std::vector<int>({1})); // --> v.emplace_back({1});


https://reviews.llvm.org/D32767

Files:
  clang-tidy/modernize/UseEmplaceCheck.cpp
  test/clang-tidy/modernize-use-emplace.cpp


Index: test/clang-tidy/modernize-use-emplace.cpp
===================================================================
--- test/clang-tidy/modernize-use-emplace.cpp
+++ test/clang-tidy/modernize-use-emplace.cpp
@@ -4,9 +4,19 @@
 // RUN:               value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}]}" -- -std=c++11
 
 namespace std {
+template <typename>
+class initializer_list
+{
+public:
+  initializer_list() noexcept {}
+};
+
 template <typename T>
 class vector {
 public:
+  vector() = default;
+  vector(initializer_list<T>) {}
+
   void push_back(const T &) {}
   void push_back(T &&) {}
 
@@ -455,3 +465,16 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: v.emplace_back(42);
 }
+
+void testInitializerList() {
+  std::vector<std::vector<int>> v;
+  v.push_back(std::vector<int>({1}));
+  // Test against the bug reported in PR32896.
+
+  v.push_back({{2}});
+
+  using PairIntVector = std::pair<int, std::vector<int>>;
+  std::vector<PairIntVector> x;
+  x.push_back(PairIntVector(3, {4}));
+  x.push_back({5, {6}});
+}
Index: clang-tidy/modernize/UseEmplaceCheck.cpp
===================================================================
--- clang-tidy/modernize/UseEmplaceCheck.cpp
+++ clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -20,6 +20,10 @@
   return Node.hasExplicitTemplateArgs();
 }
 
+AST_MATCHER(CXXStdInitializerListExpr, cxxStdInitializerListExpr) {
+  return true;
+}
+
 const auto DefaultContainersWithPushBack =
     "::std::vector; ::std::list; ::std::deque";
 const auto DefaultSmartPointers =
@@ -74,7 +78,8 @@
   // emplace_back can't access private constructor.
   auto IsPrivateCtor = hasDeclaration(cxxConstructorDecl(isPrivate()));
 
-  auto HasInitList = has(ignoringImplicit(initListExpr()));
+  auto HasInitList = anyOf(has(ignoringImplicit(initListExpr())),
+                           has(cxxStdInitializerListExpr()));
   // FIXME: Discard 0/NULL (as nullptr), static inline const data members,
   // overloaded functions and template names.
   auto SoughtConstructExpr =


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32767.97516.patch
Type: text/x-patch
Size: 2074 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170502/69c9985e/attachment-0001.bin>


More information about the cfe-commits mailing list