aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kuderski <kubakuderski@gmail.com>2017-05-22 01:56:33 +0000
committerJakub Kuderski <kubakuderski@gmail.com>2017-05-22 01:56:33 +0000
commitb957708c5fdeebef68d3c26ad7c7d28fef715d66 (patch)
tree8aeed14d9d6366a161b8a49484bb094fe4538683
parentd1c23f71840980fabc4ed38625989841afe0fd54 (diff)
[clang-tidy] Fix PR32896, PR33058: detect initializer lists in modernize-use-empalcerelease_40
Summary: The patch is backported from: r302281 to fix the 4.0.1 release blocker PR33058. This patch fixes [[ https://bugs.llvm.org/show_bug.cgi?id=32896 | PR32896 ]]. 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}); ``` Reviewers: Prazek, alexfh, aaron.ballman Reviewed By: Prazek, alexfh, aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D32767 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/branches/release_40@303524 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--clang-tidy/modernize/UseEmplaceCheck.cpp14
-rw-r--r--test/clang-tidy/modernize-use-emplace.cpp23
2 files changed, 36 insertions, 1 deletions
diff --git a/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tidy/modernize/UseEmplaceCheck.cpp
index 4084454c..214354f9 100644
--- a/clang-tidy/modernize/UseEmplaceCheck.cpp
+++ b/clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -20,6 +20,14 @@ static const auto DefaultContainersWithPushBack =
static const auto DefaultSmartPointers =
"::std::shared_ptr; ::std::unique_ptr; ::std::auto_ptr; ::std::weak_ptr";
+namespace {
+namespace impl {
+// FIXME: This matcher should be replaced by a matcher from ASTMatcher.h
+const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt,
+ CXXStdInitializerListExpr> cxxStdInitializerListExpr;
+} // namespace impl
+} // namespace
+
UseEmplaceCheck::UseEmplaceCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
ContainersWithPushBack(utils::options::parseStringList(Options.get(
@@ -69,7 +77,11 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
// emplace_back can't access private constructor.
auto isPrivateCtor = hasDeclaration(cxxConstructorDecl(isPrivate()));
- auto hasInitList = has(ignoringImplicit(initListExpr()));
+ auto hasInitList = anyOf(has(ignoringImplicit(initListExpr())),
+ has(impl::cxxStdInitializerListExpr()));
+ // FIXME: Replace internal C++ initializer list matcher with one from
+ // ASTMatchers.h
+
// FIXME: Discard 0/NULL (as nullptr), static inline const data members,
// overloaded functions and template names.
auto soughtConstructExpr =
diff --git a/test/clang-tidy/modernize-use-emplace.cpp b/test/clang-tidy/modernize-use-emplace.cpp
index a82a3a5b..403022f0 100644
--- a/test/clang-tidy/modernize-use-emplace.cpp
+++ b/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 &&) {}
@@ -422,3 +432,16 @@ void testWithDtor() {
// 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}});
+}