Skip to content

Commit

Permalink
[clang-tidy] Fix bug in modernize-use-emplace (#66169)
Browse files Browse the repository at this point in the history
emplace_back cannot construct an aggregate with arguments used to
initialize the aggregate.
Closes #62387

Test plan: Added test test from #62387 which contains code that should
not be replaced by the check.
  • Loading branch information
ccotter committed Jan 4, 2024
1 parent a0c19bd commit 03ef103
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
16 changes: 11 additions & 5 deletions clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ using namespace clang::ast_matchers;
namespace clang::tidy::modernize {

namespace {
AST_MATCHER_P(InitListExpr, initCountLeq, unsigned, N) {
return Node.getNumInits() <= N;
}

// Identical to hasAnyName, except it does not take template specifiers into
// account. This is used to match the functions names as in
// DefaultEmplacyFunctions below without caring about the template types of the
Expand Down Expand Up @@ -205,11 +209,13 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto HasConstructExpr = has(ignoringImplicit(SoughtConstructExpr));

// allow for T{} to be replaced, even if no CTOR is declared
auto HasConstructInitListExpr = has(initListExpr(anyOf(
allOf(has(SoughtConstructExpr),
has(cxxConstructExpr(argumentCountIs(0)))),
has(cxxBindTemporaryExpr(has(SoughtConstructExpr),
has(cxxConstructExpr(argumentCountIs(0))))))));
auto HasConstructInitListExpr =
has(initListExpr(initCountLeq(1),
anyOf(allOf(has(SoughtConstructExpr),
has(cxxConstructExpr(argumentCountIs(0)))),
has(cxxBindTemporaryExpr(
has(SoughtConstructExpr),
has(cxxConstructExpr(argumentCountIs(0))))))));
auto HasBracedInitListExpr =
anyOf(has(cxxBindTemporaryExpr(HasConstructInitListExpr)),
HasConstructInitListExpr);
Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ Changes in existing checks
false-positives when constructing the container with ``count`` copies of
elements with value ``value``.

- Improved :doc:`modernize-use-emplace
<clang-tidy/checks/modernize/use-emplace>` to not replace aggregates that
``emplace`` cannot construct with aggregate initialization.

- Improved :doc:`modernize-use-equals-delete
<clang-tidy/checks/modernize/use-equals-delete>` check to ignore
false-positives when special member function is actually used or implicit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,11 @@ struct NonTrivialWithVector {
std::vector<int> it;
};

struct NonTrivialWithIntAndVector {
int x;
std::vector<int> it;
};

struct NonTrivialWithCtor {
NonTrivialWithCtor();
NonTrivialWithCtor(std::vector<int> const&);
Expand Down Expand Up @@ -1332,6 +1337,14 @@ void testBracedInitTemporaries() {
v3.push_back(NonTrivialWithCtor{{}});
v3.push_back({{0}});
v3.push_back({{}});

std::vector<NonTrivialWithIntAndVector> v4;

// These should not be noticed or fixed; after the correction, the code won't
// compile.
v4.push_back(NonTrivialWithIntAndVector{1, {}});
v4.push_back(NonTrivialWithIntAndVector{});
v4.push_back({});
}

void testWithPointerTypes() {
Expand Down

0 comments on commit 03ef103

Please sign in to comment.