This revision was automatically updated to reflect the committed changes. Closed by commit rGa156a0e28df4: [ASTMatchers] Add hasPlacementArg and hasAnyPlacementArg traversal matcher for… (authored by njames93).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73562/new/ https://reviews.llvm.org/D73562 Files: clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -3124,5 +3124,45 @@ EXPECT_TRUE(notMatches("template<typename T> class A {};", Matcher)); } +TEST(CXXNewExpr, Array) { + StatementMatcher NewArray = cxxNewExpr(isArray()); + + EXPECT_TRUE(matches("void foo() { int *Ptr = new int[10]; }", NewArray)); + EXPECT_TRUE(notMatches("void foo() { int *Ptr = new int; }", NewArray)); + + StatementMatcher NewArraySize10 = + cxxNewExpr(hasArraySize(integerLiteral(equals(10)))); + EXPECT_TRUE( + matches("void foo() { int *Ptr = new int[10]; }", NewArraySize10)); + EXPECT_TRUE( + notMatches("void foo() { int *Ptr = new int[20]; }", NewArraySize10)); +} + +TEST(CXXNewExpr, PlacementArgs) { + StatementMatcher IsPlacementNew = cxxNewExpr(hasAnyPlacementArg(anything())); + + EXPECT_TRUE(matches(R"( + void* operator new(decltype(sizeof(void*)), void*); + int *foo(void* Storage) { + return new (Storage) int; + })", + IsPlacementNew)); + + EXPECT_TRUE(matches(R"( + void* operator new(decltype(sizeof(void*)), void*, unsigned); + int *foo(void* Storage) { + return new (Storage, 16) int; + })", + cxxNewExpr(hasPlacementArg( + 1, ignoringImpCasts(integerLiteral(equals(16))))))); + + EXPECT_TRUE(notMatches(R"( + void* operator new(decltype(sizeof(void*)), void*); + int *foo(void* Storage) { + return new int; + })", + IsPlacementNew)); +} + } // namespace ast_matchers } // namespace clang Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -243,6 +243,7 @@ REGISTER_MATCHER(hasAnyDeclaration); REGISTER_MATCHER(hasAnyName); REGISTER_MATCHER(hasAnyParameter); + REGISTER_MATCHER(hasAnyPlacementArg); REGISTER_MATCHER(hasAnySelector); REGISTER_MATCHER(hasAnySubstatement); REGISTER_MATCHER(hasAnyTemplateArgument); @@ -304,6 +305,7 @@ REGISTER_MATCHER(hasReceiverType); REGISTER_MATCHER(hasReplacementType); REGISTER_MATCHER(hasReturnValue); + REGISTER_MATCHER(hasPlacementArg); REGISTER_MATCHER(hasSelector); REGISTER_MATCHER(hasSingleDecl); REGISTER_MATCHER(hasSize); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6783,6 +6783,35 @@ return Node.isArray(); } +/// Matches placement new expression arguments. +/// +/// Given: +/// \code +/// MyClass *p1 = new (Storage, 16) MyClass(); +/// \endcode +/// cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16)))) +/// matches the expression 'new (Storage, 16) MyClass()'. +AST_MATCHER_P2(CXXNewExpr, hasPlacementArg, unsigned, Index, + internal::Matcher<Expr>, InnerMatcher) { + return Node.getNumPlacementArgs() > Index && + InnerMatcher.matches(*Node.getPlacementArg(Index), Finder, Builder); +} + +/// Matches any placement new expression arguments. +/// +/// Given: +/// \code +/// MyClass *p1 = new (Storage) MyClass(); +/// \endcode +/// cxxNewExpr(hasAnyPlacementArg(anything())) +/// matches the expression 'new (Storage, 16) MyClass()'. +AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>, + InnerMatcher) { + return llvm::any_of(Node.placement_arguments(), [&](const Expr *Arg) { + return InnerMatcher.matches(*Arg, Finder, Builder); + }); +} + /// Matches array new expressions with a given array size. /// /// Given: Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -5311,6 +5311,16 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>></td><td class="name" onclick="toggle('hasAnyPlacementArg0')"><a name="hasAnyPlacementArg0Anchor">hasAnyPlacementArg</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyPlacementArg0"><pre>Matches any placement new expression arguments. + +Given: + MyClass *p1 = new (Storage) MyClass(); +cxxNewExpr(hasAnyPlacementArg(anything())) + matches the expression 'new (Storage, 16) MyClass()'. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>></td><td class="name" onclick="toggle('hasArraySize0')"><a name="hasArraySize0Anchor">hasArraySize</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasArraySize0"><pre>Matches array new expressions with a given array size. @@ -5355,6 +5365,16 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>></td><td class="name" onclick="toggle('hasPlacementArg0')"><a name="hasPlacementArg0Anchor">hasPlacementArg</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasPlacementArg0"><pre>Matches placement new expression arguments. + +Given: + MyClass *p1 = new (Storage, 16) MyClass(); +cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16)))) + matches the expression 'new (Storage, 16) MyClass()'. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('hasMethod0')"><a name="hasMethod0Anchor">hasMethod</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasMethod0"><pre>Matches the first method of a class or struct that satisfies InnerMatcher. Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -84,6 +84,8 @@ auto CanCallCtor = unless(has(ignoringImpCasts( cxxConstructExpr(hasDeclaration(decl(unless(isPublic()))))))); + auto IsPlacement = hasAnyPlacementArg(anything()); + Finder->addMatcher( cxxBindTemporaryExpr(has(ignoringParenImpCasts( cxxConstructExpr( @@ -91,7 +93,7 @@ hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( equalsBoundNode(PointerType))))), - CanCallCtor) + CanCallCtor, unless(IsPlacement)) .bind(NewExpression)), unless(isInTemplateInstantiation())) .bind(ConstructorCall)))), @@ -101,7 +103,9 @@ cxxMemberCallExpr( thisPointerType(getSmartPointerTypeMatcher()), callee(cxxMethodDecl(hasName("reset"))), - hasArgument(0, cxxNewExpr(CanCallCtor).bind(NewExpression)), + hasArgument( + 0, + cxxNewExpr(CanCallCtor, unless(IsPlacement)).bind(NewExpression)), unless(isInTemplateInstantiation())) .bind(ResetCall), this); @@ -119,8 +123,6 @@ const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType); const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression); - if (New->getNumPlacementArgs() != 0) - return; // Skip when this is a new-expression with `auto`, e.g. new auto(1) if (New->getType()->getPointeeType()->getContainedAutoType()) return; Index: clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp +++ clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp @@ -16,16 +16,13 @@ namespace tidy { namespace cert { -AST_MATCHER(CXXNewExpr, isPlacementNew) { - return Node.getNumPlacementArgs() > 0; -} - void DefaultOperatorNewAlignmentCheck::registerMatchers(MatchFinder *Finder) { // Check not applicable in C++17 (or newer). if (getLangOpts().CPlusPlus17) return; - Finder->addMatcher(cxxNewExpr(unless(isPlacementNew())).bind("new"), this); + Finder->addMatcher( + cxxNewExpr(unless(hasAnyPlacementArg(anything()))).bind("new"), this); } void DefaultOperatorNewAlignmentCheck::check(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits