summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
diff options
context:
space:
mode:
authorEtienne Bergeron <etienneb@google.com>2016-04-15 16:31:15 +0000
committerEtienne Bergeron <etienneb@google.com>2016-04-15 16:31:15 +0000
commit3c5be6c9a72bad003348459a578b6b37678b075e (patch)
tree45050b741332121ab3581141e4fafd2e72ff0a68 /clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp
parent19124d3d7e01fd0f88e4884e92f757f3801a1e86 (diff)
downloadbcm5719-llvm-3c5be6c9a72bad003348459a578b6b37678b075e.tar.gz
bcm5719-llvm-3c5be6c9a72bad003348459a578b6b37678b075e.zip
[clang-tidy] Add checker for operations between integrals and pointers
Summary: This check is finding suspicious operations involving pointers and integral types; which are most likely bugs. Examples: subversion/v1_6/subversion/libsvn_subr/utf.c ``` static const char * fuzzy_escape(const char *src, apr_size_t len, apr_pool_t *pool) { [...] while (src_orig < src_end) { if (! svn_ctype_isascii(*src_orig) || src_orig == '\0') // Should be *src_orig { ``` apache2/v2_2_23/modules/metadata/mod_headers.c ``` static char *parse_format_tag(apr_pool_t *p, format_tag *tag, const char **sa) { [...] tag->arg = '\0'; // ERROR: tag->arg has type char* /* grab the argument if there is one */ if (*s == '{') { ++s; tag->arg = ap_getword(p,&s,'}'); } ``` Reviewers: alexfh Subscribers: Eugene.Zelenko, cfe-commits Differential Revision: http://reviews.llvm.org/D19118 llvm-svn: 266450
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/PointerAndIntegralOperationCheck.cpp104
1 files changed, 104 insertions, 0 deletions
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
OpenPOWER on IntegriCloud