SilverGeri updated this revision to Diff 77015.
SilverGeri added a comment.
checks `if (p != 0)` conditions, too
https://reviews.llvm.org/D21298
Files:
clang-tidy/misc/CMakeLists.txt
clang-tidy/misc/DeleteNullPointerCheck.cpp
clang-tidy/misc/DeleteNullPointerCheck.h
clang-tidy/misc/MiscTidyModule.cpp
docs/clang-tidy/checks/list.rst
docs/clang-tidy/checks/misc-delete-null-pointer.rst
test/clang-tidy/misc-delete-null-pointer.cpp
Index: test/clang-tidy/misc-delete-null-pointer.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-delete-null-pointer.cpp
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s misc-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) [misc-delete-null-pointer]
+ delete p;
+ }
+ // CHECK-FIXES: delete p;
+ int *p3 = new int[3];
+ if (p3)
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if statement is unnecessary (deleting null pointer has no effect) [misc-delete-null-pointer]
+ delete[] p3;
+ // CHECK-FIXES: delete[] p3;
+
+ if (NULL != p) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if statement is unnecessary (deleting null pointer has no effect) [misc-delete-null-pointer]
+ delete p;
+ }
+ // CHECK-FIXES: delete p;
+
+ if (p != nullptr) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if statement is unnecessary (deleting null pointer has no effect) [misc-delete-null-pointer]
+ delete p;
+ }
+ // CHECK-FIXES: delete p;
+
+ if (p != 0) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if statement is unnecessary (deleting null pointer has no effect) [misc-delete-null-pointer]
+ delete p;
+ }
+ // CHECK-FIXES: delete p;
+}
+
+void g() {
+ int *p, *p2;
+ if (p)
+ delete p2;
+
+ if (p && p2)
+ delete p;
+
+ if (p2) {
+ int x = 5;
+ delete p2;
+ }
+}
Index: docs/clang-tidy/checks/misc-delete-null-pointer.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-delete-null-pointer.rst
@@ -0,0 +1,12 @@
+.. title:: clang-tidy - misc-delete-null-pointer
+
+misc-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
@@ -58,6 +58,7 @@
misc-bool-pointer-implicit-conversion
misc-dangling-handle
misc-definitions-in-headers
+ misc-delete-null-pointer
misc-fold-init-type
misc-forward-declaration-namespace
misc-inaccurate-erase
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -12,6 +12,7 @@
#include "../ClangTidyModuleRegistry.h"
#include "ArgumentCommentCheck.h"
#include "AssertSideEffectCheck.h"
+#include "DeleteNullPointerCheck.h"
#include "MisplacedConstCheck.h"
#include "UnconventionalAssignOperatorCheck.h"
#include "BoolPointerImplicitConversionCheck.h"
@@ -63,6 +64,8 @@
CheckFactories.registerCheck<ArgumentCommentCheck>("misc-argument-comment");
CheckFactories.registerCheck<AssertSideEffectCheck>(
"misc-assert-side-effect");
+ CheckFactories.registerCheck<DeleteNullPointerCheck>(
+ "misc-delete-null-pointer");
CheckFactories.registerCheck<MisplacedConstCheck>(
"misc-misplaced-const");
CheckFactories.registerCheck<UnconventionalAssignOperatorCheck>(
Index: clang-tidy/misc/DeleteNullPointerCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/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_MISC_DELETE_NULL_POINTER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DELETE_NULL_POINTER_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-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 misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DELETE_NULL_POINTER_H
Index: clang-tidy/misc/DeleteNullPointerCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/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 misc {
+
+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 misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -3,6 +3,7 @@
add_clang_library(clangTidyMiscModule
ArgumentCommentCheck.cpp
AssertSideEffectCheck.cpp
+ DeleteNullPointerCheck.cpp
MisplacedConstCheck.cpp
UnconventionalAssignOperatorCheck.cpp
BoolPointerImplicitConversionCheck.cpp
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits