SilverGeri updated this revision to Diff 77972. SilverGeri added a comment.
update tests with "CHECK-FIXES-NOT" parts https://reviews.llvm.org/D21298 Files: clang-tidy/readability/CMakeLists.txt clang-tidy/readability/DeleteNullPointerCheck.cpp clang-tidy/readability/DeleteNullPointerCheck.h clang-tidy/readability/ReadabilityTidyModule.cpp docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/readability-delete-null-pointer.rst test/clang-tidy/readability-delete-null-pointer.cpp
Index: test/clang-tidy/readability-delete-null-pointer.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability-delete-null-pointer.cpp @@ -0,0 +1,58 @@ +// RUN: %check_clang_tidy %s readability-delete-null-pointer %t + +#include <cstdlib> + +void f() { + int *p = 0; + if (p) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer] + delete p; + } + // CHECK-FIXES-NOT: if (p) { + // CHECK-FIXES: delete p; + + int *p2 = new int[3]; + if (p2) + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer] + delete[] p2; + // CHECK-FIXES-NOT: if (p2) + // CHECK-FIXES: delete[] p2; + + int *p3 = 0; + if (NULL != p3) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer] + delete p3; + } + // CHECK-FIXES-NOT: if (NULL != p3) { + // CHECK-FIXES: delete p3; + + int *p4 = nullptr; + if (p4 != nullptr) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer] + delete p4; + } + // CHECK-FIXES-NOT: if (p4 != nullptr) { + // CHECK-FIXES: delete p4; + + char *c; + if (c != 0) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'if' statement is unnecessary; deleting null pointer has no effect [readability-delete-null-pointer] + delete c; + } + // CHECK-FIXES-NOT: if (c != 0) { + // CHECK-FIXES: delete c; +} + +void g() { + int *p5, *p6; + if (p5) + delete p6; + + if (p5 && p6) + delete p5; + + if (p6) { + int x = 5; + delete p6; + } +} \ No newline at end of file Index: docs/clang-tidy/checks/readability-delete-null-pointer.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/readability-delete-null-pointer.rst @@ -0,0 +1,12 @@ +.. title:: clang-tidy - readability-delete-null-pointer + +readability-delete-null-pointer +=============================== + +Checks the 'if' statements where a pointer's existence is checked and then deletes the pointer. +The check is unnecessary as deleting a nullpointer has no effect. + +.. code:: c++ + int *p; + if (p) + delete p; Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -123,6 +123,7 @@ readability-avoid-const-params-in-decls readability-braces-around-statements readability-container-size-empty + readability-delete-null-pointer readability-deleted-default readability-else-after-return readability-function-size Index: clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tidy/readability/ReadabilityTidyModule.cpp @@ -13,6 +13,7 @@ #include "AvoidConstParamsInDecls.h" #include "BracesAroundStatementsCheck.h" #include "ContainerSizeEmptyCheck.h" +#include "DeleteNullPointerCheck.h" #include "DeletedDefaultCheck.h" #include "ElseAfterReturnCheck.h" #include "FunctionSizeCheck.h" @@ -44,6 +45,8 @@ "readability-braces-around-statements"); CheckFactories.registerCheck<ContainerSizeEmptyCheck>( "readability-container-size-empty"); + CheckFactories.registerCheck<DeleteNullPointerCheck>( + "readability-delete-null-pointer"); CheckFactories.registerCheck<DeletedDefaultCheck>( "readability-deleted-default"); CheckFactories.registerCheck<ElseAfterReturnCheck>( Index: clang-tidy/readability/DeleteNullPointerCheck.h =================================================================== --- /dev/null +++ clang-tidy/readability/DeleteNullPointerCheck.h @@ -0,0 +1,35 @@ +//===--- DeleteNullPointerCheck.h - clang-tidy-------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETE_NULL_POINTER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETE_NULL_POINTER_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// Check whether the 'if' statement is unnecessary before calling 'delete' on a pointer. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability-delete-null-pointer.html +class DeleteNullPointerCheck : public ClangTidyCheck { +public: + DeleteNullPointerCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace readability +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETE_NULL_POINTER_H Index: clang-tidy/readability/DeleteNullPointerCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/readability/DeleteNullPointerCheck.cpp @@ -0,0 +1,66 @@ +//===--- DeleteNullPointerCheck.cpp - clang-tidy---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DeleteNullPointerCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +void DeleteNullPointerCheck::registerMatchers(MatchFinder *Finder) { + const auto DeleteExpr = + cxxDeleteExpr(has(castExpr(has(declRefExpr( + to(decl(equalsBoundNode("deletedPointer")))))))) + .bind("deleteExpr"); + + const auto PointerCondition = castExpr(hasCastKind(CK_PointerToBoolean)); + const auto BinaryPointerCheckCondition = binaryOperator( + allOf(hasEitherOperand(castExpr(hasCastKind(CK_NullToPointer))), + hasEitherOperand(ignoringImpCasts(declRefExpr())))); + + Finder->addMatcher( + ifStmt(allOf(hasCondition( + anyOf(PointerCondition, BinaryPointerCheckCondition)), + hasCondition(anyOf( + ignoringImpCasts( + declRefExpr(to(decl().bind("deletedPointer")))), + binaryOperator(hasEitherOperand(ignoringImpCasts( + declRefExpr(to(decl().bind("deletedPointer")))))))), + hasThen(anyOf( + DeleteExpr, + compoundStmt(allOf(has(DeleteExpr), statementCountIs(1))) + .bind("compound"))))) + .bind("ifWithDelete"), + this); +} + +void DeleteNullPointerCheck::check(const MatchFinder::MatchResult &Result) { + const auto *IfWithDelete = Result.Nodes.getNodeAs<IfStmt>("ifWithDelete"); + const auto *Delete = Result.Nodes.getNodeAs<CXXDeleteExpr>("deleteExpr"); + + auto D = + diag(IfWithDelete->getLocStart(), + "'if' statement is unnecessary; deleting null pointer has no effect"); + std::string ReplacementText = Lexer::getSourceText( + CharSourceRange::getTokenRange(Delete->getSourceRange()), + *Result.SourceManager, Result.Context->getLangOpts()); + ReplacementText += ';'; + + D << FixItHint::CreateReplacement(IfWithDelete->getSourceRange(), + ReplacementText); +} + +} // namespace readability +} // namespace tidy +} // namespace clang Index: clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tidy/readability/CMakeLists.txt +++ clang-tidy/readability/CMakeLists.txt @@ -4,6 +4,7 @@ AvoidConstParamsInDecls.cpp BracesAroundStatementsCheck.cpp ContainerSizeEmptyCheck.cpp + DeleteNullPointerCheck.cpp DeletedDefaultCheck.cpp ElseAfterReturnCheck.cpp FunctionSizeCheck.cpp
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits