diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp @@ -42,14 +42,14 @@ auto CallExpression = callExpr( - allOf( - unless(isMacroID()), unless(cxxMemberCallExpr()), - allOf(callee(namedDecl(hasAnyName("isa", "cast", "cast_or_null", - "dyn_cast", "dyn_cast_or_null")) - .bind("func")), - hasArgument( - 0, - mapAnyOf(declRefExpr, cxxMemberCallExpr).bind("arg"))))) + allOf(unless(isMacroID()), unless(cxxMemberCallExpr()), + allOf(callee(namedDecl(hasAnyName("isa", "cast", "cast_or_null", + "cast_if_present", "dyn_cast", + "dyn_cast_or_null", + "dyn_cast_if_present")) + .bind("func")), + hasArgument(0, mapAnyOf(declRefExpr, cxxMemberCallExpr) + .bind("arg"))))) .bind("rhs"); Finder->addMatcher( @@ -118,11 +118,11 @@ CharSourceRange::getTokenRange(RHS->getSourceRange()), *Result.SourceManager, getLangOpts())); - std::string Replacement("isa_and_nonnull"); + std::string Replacement("isa_and_present"); Replacement += RHSString.substr(Func->getName().size()); diag(MatchedDecl->getBeginLoc(), - "isa_and_nonnull<> is preferred over an explicit test for null " + "isa_and_present<> is preferred over an explicit test for null " "followed by calling isa<>") << FixItHint::CreateReplacement(SourceRange(MatchedDecl->getBeginLoc(), MatchedDecl->getEndLoc()), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -105,6 +105,11 @@ Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Updated :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals + ` check to + use the `*and_present` and `*if_present` templates added in + `D123901 `_. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals.rst --- a/clang-tools-extra/docs/clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals.rst @@ -26,7 +26,7 @@ if (var && isa(var)) {} // is replaced by: - if (isa_and_nonnull(var.foo())) {} + if (isa_and_present(var.foo())) {} // Other cases are ignored, e.g.: if (auto f = cast(y)->foo()) {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp @@ -17,6 +17,8 @@ X *dyn_cast(Y *); template X *dyn_cast_or_null(Y *); +template +X *dyn_cast_if_present(Y *); bool foo(Y *y, Z *z) { if (auto x = cast(y)) @@ -63,32 +65,37 @@ if (y && isa(y)) return true; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals] - // CHECK-FIXES: if (isa_and_nonnull(y)) + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals] + // CHECK-FIXES: if (isa_and_present(y)) if (z->bar() && isa(z->bar())) return true; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred - // CHECK-FIXES: if (isa_and_nonnull(z->bar())) + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred + // CHECK-FIXES: if (isa_and_present(z->bar())) if (z->bar() && cast(z->bar())) return true; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred - // CHECK-FIXES: if (isa_and_nonnull(z->bar())) + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred + // CHECK-FIXES: if (isa_and_present(z->bar())) if (z->bar() && dyn_cast(z->bar())) return true; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred - // CHECK-FIXES: if (isa_and_nonnull(z->bar())) + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred + // CHECK-FIXES: if (isa_and_present(z->bar())) if (z->bar() && dyn_cast_or_null(z->bar())) return true; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred - // CHECK-FIXES: if (isa_and_nonnull(z->bar())) + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred + // CHECK-FIXES: if (isa_and_present(z->bar())) + + if (z->bar() && dyn_cast_if_present(z->bar())) + return true; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_present<> is preferred + // CHECK-FIXES: if (isa_and_present(z->bar())) bool b = z->bar() && cast(z->bar()); - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_nonnull<> is preferred - // CHECK-FIXES: bool b = isa_and_nonnull(z->bar()); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_present<> is preferred + // CHECK-FIXES: bool b = isa_and_present(z->bar()); // These don't trigger a warning. if (auto x = cast(y)->foo())