etienneb updated this revision to Diff 53730.
etienneb added a comment.

nits


http://reviews.llvm.org/D19118

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/MiscTidyModule.cpp
  clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
  clang-tidy/misc/PointerAndIntegralOperationCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-pointer-and-integral-operation.rst
  test/clang-tidy/misc-pointer-and-integral-operation-cxx98.cpp
  test/clang-tidy/misc-pointer-and-integral-operation.cpp

Index: test/clang-tidy/misc-pointer-and-integral-operation.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-pointer-and-integral-operation.cpp
@@ -0,0 +1,30 @@
+// RUN: %check_clang_tidy %s misc-pointer-and-integral-operation %t
+
+bool* pb;
+char* pc;
+int* pi;
+
+int Test() {
+  if (pi < 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious comparison of pointer with zero
+  if (pi <= 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious comparison of pointer with zero
+
+  if (nullptr <= pb) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: suspicious comparison of pointer with null
+  if (pc < nullptr) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious comparison of pointer with null
+  if (pi > nullptr) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious comparison of pointer with null
+
+  return 1;
+}
+
+int Valid() {
+  *pb = false;
+  *pc = '\0';
+
+  pi += (pi != nullptr);
+  pi -= (pi == nullptr);
+  pc += (pb != nullptr);
+}
Index: test/clang-tidy/misc-pointer-and-integral-operation-cxx98.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-pointer-and-integral-operation-cxx98.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s misc-pointer-and-integral-operation %t -- -- -std=c++98
+
+bool* pb;
+char* pc;
+int* pi;
+
+int Test() {
+  pb = false;
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: suspicious assignment from bool to pointer
+  pc = '\0';
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: suspicious assignment from char to pointer
+
+  pb = (false?false:false);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: suspicious assignment from bool to pointer
+  pb = (4 != 5?false:false);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: suspicious assignment from bool to pointer
+
+  if (pb < false) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and bool literal
+  if (pb != false) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and bool literal
+  if (pc < '\0') return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and character literal
+  if (pc != '\0') return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and character literal
+  if (pi < '\0') return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and character literal
+  if (pi != '\0') return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious operation between pointer and character literal
+
+  return 1;
+}
+
+int Valid() {
+  *pb = false;
+  *pc = '\0';
+
+  pb += 0;
+  pc += 0;
+  pi += 0;
+
+  pb += (pb != 0);
+  pc += (pc != 0);
+  pi += (pi != 0);
+}
Index: docs/clang-tidy/checks/misc-pointer-and-integral-operation.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-pointer-and-integral-operation.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - misc-pointer-and-integral-operation
+
+misc-pointer-and-integral-operation
+===================================
+
+Looks for operation involving pointers and integral types. A common mistake is
+to forget to dereference a pointer. These errors may be detected when a pointer
+object is compare to an object with integral type.
+
+
+Examples:
+
+.. code:: c++
+
+  char* ptr;
+  if ((ptr = malloc(...)) < nullptr)   // Pointer comparison with operator '<'
+    ...                                // Should probably be '!='
+
+  if (ptr == '\0')   // Should probably be *ptr
+    ... 
+
+  void Prcess(std::string path, bool* error) {
+    [...]
+    if (error != false)  // Should probably be *error
+      ...
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -64,6 +64,7 @@
    misc-new-delete-overloads
    misc-noexcept-move-constructor
    misc-non-copyable-objects
+   misc-pointer-and-integral-operation
    misc-sizeof-container
    misc-static-assert
    misc-string-integer-assignment
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -103,6 +103,11 @@
   Warns when there is a explicit redundant cast of a calculation result to a
   bigger type.
 
+- New `misc-pointer-and-integral-operation
+  <http://clang.llvm.org/extra/clang-tidy/checks/misc-misc-pointer-and-integral-operation.html>`_ check
+
+  Warns about suspicious operations involving pointers and integral types.
+
 - New `misc-string-literal-with-embedded-nul
   <http://clang.llvm.org/extra/clang-tidy/checks/misc-string-literal-with-embedded-nul.html>`_ check
 
Index: clang-tidy/misc/PointerAndIntegralOperationCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/PointerAndIntegralOperationCheck.h
@@ -0,0 +1,35 @@
+//===--- PointerAndIntegralOperationCheck.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_POINTER_AND_INTEGRAL_OPERATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_POINTER_AND_INTEGRAL_OPERATION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Find suspicious expressions involving pointer and integral types.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-pointer-and-integral-operation.html
+class PointerAndIntegralOperationCheck : public ClangTidyCheck {
+public:
+  PointerAndIntegralOperationCheck(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_POINTER_AND_INTEGRAL_OPERATION_H
Index: clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
@@ -0,0 +1,104 @@
+//===--- PointerAndIntegralOperationCheck.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 "PointerAndIntegralOperationCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void PointerAndIntegralOperationCheck::registerMatchers(MatchFinder *Finder) {
+  const auto PointerExpr = expr(hasType(pointerType()));
+  const auto BoolExpr = ignoringParenImpCasts(hasType(booleanType()));
+  const auto CharExpr = ignoringParenImpCasts(hasType(isAnyCharacter()));
+
+  const auto BinOpWithPointerExpr =
+      binaryOperator(unless(anyOf(hasOperatorName(","), hasOperatorName("="))),
+                     hasEitherOperand(PointerExpr));
+
+  const auto AssignToPointerExpr =
+      binaryOperator(hasOperatorName("="), hasLHS(PointerExpr));
+
+  const auto CompareToPointerExpr =
+      binaryOperator(anyOf(hasOperatorName("<"), hasOperatorName("<="),
+                           hasOperatorName(">"), hasOperatorName(">=")),
+                     hasEitherOperand(PointerExpr));
+
+  // Detect expression like: ptr = (x != y);
+  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(BoolExpr))
+                         .bind("assign-bool-to-pointer"),
+                     this);
+
+  // Detect expression like: ptr = A[i]; where A is char*.
+  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(CharExpr))
+                         .bind("assign-char-to-pointer"),
+                     this);
+
+  // Detect expression like: ptr < false;
+  Finder->addMatcher(
+      binaryOperator(BinOpWithPointerExpr,
+                     hasEitherOperand(ignoringParenImpCasts(cxxBoolLiteral())))
+          .bind("pointer-and-bool-literal"),
+      this);
+
+  // Detect expression like: ptr < 'a';
+  Finder->addMatcher(binaryOperator(BinOpWithPointerExpr,
+                                    hasEitherOperand(ignoringParenImpCasts(
+                                        characterLiteral())))
+                         .bind("pointer-and-char-literal"),
+                     this);
+
+  // Detect expression like: ptr < 0;
+  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
+                                    hasEitherOperand(ignoringParenImpCasts(
+                                        integerLiteral(equals(0)))))
+                         .bind("compare-pointer-to-zero"),
+                     this);
+
+  // Detect expression like: ptr < nullptr;
+  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
+                                    hasEitherOperand(ignoringParenImpCasts(
+                                        cxxNullPtrLiteralExpr())))
+                         .bind("compare-pointer-to-null"),
+                     this);
+}
+
+void PointerAndIntegralOperationCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  if (const auto *E =
+          Result.Nodes.getNodeAs<BinaryOperator>("assign-bool-to-pointer")) {
+    diag(E->getOperatorLoc(), "suspicious assignment from bool to pointer");
+  } else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
+                 "assign-char-to-pointer")) {
+    diag(E->getOperatorLoc(), "suspicious assignment from char to pointer");
+  } else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
+                 "pointer-and-bool-literal")) {
+    diag(E->getOperatorLoc(),
+         "suspicious operation between pointer and bool literal");
+  } else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
+                 "pointer-and-char-literal")) {
+    diag(E->getOperatorLoc(),
+         "suspicious operation between pointer and character literal");
+  } else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
+                 "compare-pointer-to-zero")) {
+    diag(E->getOperatorLoc(), "suspicious comparison of pointer with zero");
+  } else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
+                 "compare-pointer-to-null")) {
+    diag(E->getOperatorLoc(),
+         "suspicious comparison of pointer with null expression");
+  }
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -28,6 +28,7 @@
 #include "NewDeleteOverloadsCheck.h"
 #include "NoexceptMoveConstructorCheck.h"
 #include "NonCopyableObjects.h"
+#include "PointerAndIntegralOperationCheck.h"
 #include "SizeofContainerCheck.h"
 #include "StaticAssertCheck.h"
 #include "StringIntegerAssignmentCheck.h"
@@ -85,6 +86,8 @@
         "misc-noexcept-move-constructor");
     CheckFactories.registerCheck<NonCopyableObjectsCheck>(
         "misc-non-copyable-objects");
+    CheckFactories.registerCheck<PointerAndIntegralOperationCheck>(
+        "misc-pointer-and-integral-operation");
     CheckFactories.registerCheck<SizeofContainerCheck>("misc-sizeof-container");
     CheckFactories.registerCheck<StaticAssertCheck>(
         "misc-static-assert");
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -20,6 +20,7 @@
   NewDeleteOverloadsCheck.cpp
   NoexceptMoveConstructorCheck.cpp
   NonCopyableObjects.cpp
+  PointerAndIntegralOperationCheck.cpp
   SizeofContainerCheck.cpp
   StaticAssertCheck.cpp
   StringIntegerAssignmentCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to