Skip to content

Commit f8d872c

Browse files
committedMay 5, 2017
[clang-tidy] Fix PR32896: detect initializer lists in modernize-use-empalce
Summary: 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 llvm-svn: 302281
1 parent 807790a commit f8d872c

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed
 

‎clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {
2020
return Node.hasExplicitTemplateArgs();
2121
}
2222

23+
namespace impl {
24+
// FIXME: This matcher should be replaced by a matcher from ASTMatcher.h
25+
const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt,
26+
CXXStdInitializerListExpr> cxxStdInitializerListExpr;
27+
} // namespace impl
28+
2329
const auto DefaultContainersWithPushBack =
2430
"::std::vector; ::std::list; ::std::deque";
2531
const auto DefaultSmartPointers =
@@ -74,7 +80,11 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
7480
// emplace_back can't access private constructor.
7581
auto IsPrivateCtor = hasDeclaration(cxxConstructorDecl(isPrivate()));
7682

77-
auto HasInitList = has(ignoringImplicit(initListExpr()));
83+
auto HasInitList = anyOf(has(ignoringImplicit(initListExpr())),
84+
has(impl::cxxStdInitializerListExpr()));
85+
// FIXME: Replace internal C++ initializer list matcher with one from
86+
// ASTMatchers.h
87+
7888
// FIXME: Discard 0/NULL (as nullptr), static inline const data members,
7989
// overloaded functions and template names.
8090
auto SoughtConstructExpr =

‎clang-tools-extra/test/clang-tidy/modernize-use-emplace.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@
44
// RUN: value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}]}" -- -std=c++11
55

66
namespace std {
7+
template <typename>
8+
class initializer_list
9+
{
10+
public:
11+
initializer_list() noexcept {}
12+
};
13+
714
template <typename T>
815
class vector {
916
public:
17+
vector() = default;
18+
vector(initializer_list<T>) {}
19+
1020
void push_back(const T &) {}
1121
void push_back(T &&) {}
1222

@@ -455,3 +465,16 @@ void testWithDtor() {
455465
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
456466
// CHECK-FIXES: v.emplace_back(42);
457467
}
468+
469+
void testInitializerList() {
470+
std::vector<std::vector<int>> v;
471+
v.push_back(std::vector<int>({1}));
472+
// Test against the bug reported in PR32896.
473+
474+
v.push_back({{2}});
475+
476+
using PairIntVector = std::pair<int, std::vector<int>>;
477+
std::vector<PairIntVector> x;
478+
x.push_back(PairIntVector(3, {4}));
479+
x.push_back({5, {6}});
480+
}

0 commit comments

Comments
 (0)
Please sign in to comment.