Skip to content

Conversation

@ccotter
Copy link
Contributor

@ccotter ccotter commented Sep 13, 2023

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.

@ccotter ccotter requested a review from a team as a code owner September 13, 2023 04:47
emplace_back cannot construct an aggregate with arguments used to initialize the aggregate. Closes llvm#62387 Test plan: Added test case from llvm#62387 which contains code that should not be replaced by the check.
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2023

@llvm/pr-subscribers-clang-tidy

Changes 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.

Full diff: https://github.com/llvm/llvm-project/pull/66169.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+11-5)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp (+16)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 554abcd900e329c..e4455d6f9c1feec 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -13,6 +13,10 @@ using namespace clang::ast_matchers; namespace clang::tidy::modernize { namespace { +AST_MATCHER_P(InitListExpr, initCountIs, 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 @@ -207,11 +211,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(anyOf(initCountIs(0), initCountIs(1)), + anyOf(allOf(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0)))), + has(cxxBindTemporaryExpr( + has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0)))))))); auto HasBracedInitListExpr = anyOf(has(cxxBindTemporaryExpr(HasConstructInitListExpr)), HasConstructInitListExpr); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 19c977977f9044c..694beeb98a54e36 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -247,6 +247,10 @@ Changes in existing checks <clang-tidy/checks/modernize/loop-convert>` to support for-loops with iterators initialized by free functions like ``begin``, ``end``, or ``size``. +- Improved :doc:`modernize-use-emplace + <clang-tidy/checks/modernize/use-emplace>` to not replace aggregates that + ``emplace_back`` 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. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp index fead2b6151d0218..74edf0760bb324d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp @@ -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&); @@ -1332,6 +1337,17 @@ 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, {}}); + // CHECK-FIXES: v4.push_back(NonTrivialWithIntAndVector{1, {}}); + v4.push_back(NonTrivialWithIntAndVector{}); + // CHECK-FIXES: v4.push_back(NonTrivialWithIntAndVector{}); + v4.push_back({}); + // CHECK-FIXES: v4.push_back({}); } void testWithPointerTypes() { 
Copy link
Member

@PiotrZSL PiotrZSL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, check comments, and verify if check shouldn't be made more strict.

@PiotrZSL
Copy link
Member

clang-format need to be run on this change.
Looks like aggregate initialization is +- supported in C++20, maybe work a change.

@PiotrZSL PiotrZSL merged commit 03ef103 into llvm:main Jan 4, 2024
alanzhao1 pushed a commit to alanzhao1/llvm-project that referenced this pull request Jan 4, 2024
Manually formating code via clang-format after previous commit merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

4 participants