summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy')
-rw-r--r--clang-tools-extra/clang-tidy/misc/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp3
-rw-r--r--clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp104
-rw-r--r--clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.h35
4 files changed, 143 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index c3ee5c3a6b2..ae0b0dfdb78 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_library(clangTidyMiscModule
NewDeleteOverloadsCheck.cpp
NoexceptMoveConstructorCheck.cpp
NonCopyableObjects.cpp
+ PointerAndIntegralOperationCheck.cpp
SizeofContainerCheck.cpp
StaticAssertCheck.cpp
StringIntegerAssignmentCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index df335fa6e51..bbc0eb714e8 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -29,6 +29,7 @@
#include "NewDeleteOverloadsCheck.h"
#include "NoexceptMoveConstructorCheck.h"
#include "NonCopyableObjects.h"
+#include "PointerAndIntegralOperationCheck.h"
#include "SizeofContainerCheck.h"
#include "StaticAssertCheck.h"
#include "StringIntegerAssignmentCheck.h"
@@ -88,6 +89,8 @@ public:
"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");
diff --git a/clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp b/clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
new file mode 100644
index 00000000000..e154e8dac81
--- /dev/null
+++ b/clang-tools-extra/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
diff --git a/clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.h b/clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.h
new file mode 100644
index 00000000000..996253e8e69
--- /dev/null
+++ b/clang-tools-extra/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
OpenPOWER on IntegriCloud