[clang-tools-extra] r310584 - [clang-tidy] Add modernize-use-emplace.IgnoreImplicitConstructors option

Alexander Kornienko via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 05:19:05 PDT 2017


Author: alexfh
Date: Thu Aug 10 05:19:05 2017
New Revision: 310584

URL: http://llvm.org/viewvc/llvm-project?rev=310584&view=rev
Log:
[clang-tidy] Add modernize-use-emplace.IgnoreImplicitConstructors option

Added:
    clang-tools-extra/trunk/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.cpp
    clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.h

Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.cpp?rev=310584&r1=310583&r2=310584&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.cpp Thu Aug 10 05:19:05 2017
@@ -30,6 +30,7 @@ const auto DefaultTupleMakeFunctions = "
 
 UseEmplaceCheck::UseEmplaceCheck(StringRef Name, ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
+      IgnoreImplicitConstructors(Options.get("IgnoreImplicitConstructors", 0)),
       ContainersWithPushBack(utils::options::parseStringList(Options.get(
           "ContainersWithPushBack", DefaultContainersWithPushBack))),
       SmartPointers(utils::options::parseStringList(
@@ -120,9 +121,13 @@ void UseEmplaceCheck::registerMatchers(M
 
 void UseEmplaceCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call");
-  const auto *InnerCtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");
+  const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");
   const auto *MakeCall = Result.Nodes.getNodeAs<CallExpr>("make");
-  assert((InnerCtorCall || MakeCall) && "No push_back parameter matched");
+  assert((CtorCall || MakeCall) && "No push_back parameter matched");
+
+  if (IgnoreImplicitConstructors && CtorCall && CtorCall->getNumArgs() >= 1 &&
+      CtorCall->getArg(0)->getSourceRange() == CtorCall->getSourceRange())
+    return;
 
   const auto FunctionNameSourceRange = CharSourceRange::getCharRange(
       Call->getExprLoc(), Call->getArg(0)->getExprLoc());
@@ -138,14 +143,14 @@ void UseEmplaceCheck::check(const MatchF
   const SourceRange CallParensRange =
       MakeCall ? SourceRange(MakeCall->getCallee()->getLocEnd(),
                              MakeCall->getRParenLoc())
-               : InnerCtorCall->getParenOrBraceRange();
+               : CtorCall->getParenOrBraceRange();
 
   // Finish if there is no explicit constructor call.
   if (CallParensRange.getBegin().isInvalid())
     return;
 
   const SourceLocation ExprBegin =
-      MakeCall ? MakeCall->getExprLoc() : InnerCtorCall->getExprLoc();
+      MakeCall ? MakeCall->getExprLoc() : CtorCall->getExprLoc();
 
   // Range for constructor name and opening brace.
   const auto ParamCallSourceRange =

Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.h?rev=310584&r1=310583&r2=310584&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/UseEmplaceCheck.h Thu Aug 10 05:19:05 2017
@@ -33,10 +33,11 @@ public:
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
 
 private:
-  std::vector<std::string> ContainersWithPushBack;
-  std::vector<std::string> SmartPointers;
-  std::vector<std::string> TupleTypes;
-  std::vector<std::string> TupleMakeFunctions;
+  const bool IgnoreImplicitConstructors;
+  const std::vector<std::string> ContainersWithPushBack;
+  const std::vector<std::string> SmartPointers;
+  const std::vector<std::string> TupleTypes;
+  const std::vector<std::string> TupleMakeFunctions;
 };
 
 } // namespace modernize

Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp?rev=310584&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-emplace-ignore-implicit-constructors.cpp Thu Aug 10 05:19:05 2017
@@ -0,0 +1,123 @@
+// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: modernize-use-emplace.IgnoreImplicitConstructors, \
+// RUN:               value: 1}] \
+// RUN:             }" -- -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 &&) {}
+
+  template <typename... Args>
+  void emplace_back(Args &&... args){};
+  ~vector();
+};
+
+} // namespace std
+
+void testInts() {
+  std::vector<int> v;
+  v.push_back(42);
+  v.push_back(int(42));
+  v.push_back(int{42});
+  v.push_back(42.0);
+  int z;
+  v.push_back(z);
+}
+
+struct Something {
+  Something(int a, int b = 41) {}
+  Something() {}
+  void push_back(Something);
+  int getInt() { return 42; }
+};
+
+struct Convertable {
+  operator Something() { return Something{}; }
+};
+
+struct Zoz {
+  Zoz(Something, int = 42) {}
+};
+
+Zoz getZoz(Something s) { return Zoz(s); }
+
+void test_Something() {
+  std::vector<Something> v;
+
+  v.push_back(Something(1, 2));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace]
+  // CHECK-FIXES: v.emplace_back(1, 2);
+
+  v.push_back(Something{1, 2});
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(1, 2);
+
+  v.push_back(Something());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back();
+
+  v.push_back(Something{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back();
+
+  Something Different;
+  v.push_back(Something(Different.getInt(), 42));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
+
+  v.push_back(Different.getInt());
+  v.push_back(42);
+
+  Something temporary(42, 42);
+  temporary.push_back(temporary);
+  v.push_back(temporary);
+
+  v.push_back(Convertable());
+  v.push_back(Convertable{});
+  Convertable s;
+  v.push_back(s);
+}
+
+template <typename ElemType>
+void dependOnElem() {
+  std::vector<ElemType> v;
+  v.push_back(ElemType(42));
+}
+
+template <typename ContainerType>
+void dependOnContainer() {
+  ContainerType v;
+  v.push_back(Something(42));
+}
+
+void callDependent() {
+  dependOnElem<Something>();
+  dependOnContainer<std::vector<Something>>();
+}
+
+void test2() {
+  std::vector<Zoz> v;
+  v.push_back(Zoz(Something(21, 37)));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(Something(21, 37));
+
+  v.push_back(Zoz(Something(21, 37), 42));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(Something(21, 37), 42);
+
+  v.push_back(getZoz(Something(1, 2)));
+}




More information about the cfe-commits mailing list