summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorMatthias Gehre <M.Gehre@gmx.de>2015-10-12 21:53:19 +0000
committerMatthias Gehre <M.Gehre@gmx.de>2015-10-12 21:53:19 +0000
commitdc48412c938f39d51b8980db9f957cab30af671e (patch)
treefce96a2c9f21e71471a7e89d950dd04e75270430 /clang-tools-extra
parent9159ce932790cb30ed274507377c4b9aef2bff5f (diff)
downloadbcm5719-llvm-dc48412c938f39d51b8980db9f957cab30af671e.tar.gz
bcm5719-llvm-dc48412c938f39d51b8980db9f957cab30af671e.zip
[clang-tidy] new check cppcoreguidelines-pro-bounds-pointer-arithmetic
Summary: This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer. Subtraction of two pointers is not flagged by this check. Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data. This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead Depends on D13313 Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D13311 llvm-svn: 250116
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp3
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp53
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h34
-rw-r--r--clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst10
-rw-r--r--clang-tools-extra/docs/clang-tidy/checks/list.rst1
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp87
7 files changed, 189 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
index d35b9a56f94..6147914a9fe 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyCppCoreGuidelinesModule
CppCoreGuidelinesTidyModule.cpp
+ ProBoundsPointerArithmeticCheck.cpp
ProTypeConstCastCheck.cpp
ProTypeReinterpretCastCheck.cpp
ProTypeStaticCastDowncastCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
index 358bd6ec8fd..07ba15a8b4a 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -10,6 +10,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
+#include "ProBoundsPointerArithmeticCheck.h"
#include "ProTypeConstCastCheck.h"
#include "ProTypeReinterpretCastCheck.h"
#include "ProTypeStaticCastDowncastCheck.h"
@@ -22,6 +23,8 @@ namespace cppcoreguidelines {
class CppCoreGuidelinesModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<ProBoundsPointerArithmeticCheck>(
+ "cppcoreguidelines-pro-bounds-pointer-arithmetic");
CheckFactories.registerCheck<ProTypeConstCastCheck>(
"cppcoreguidelines-pro-type-const-cast");
CheckFactories.registerCheck<ProTypeReinterpretCastCheck>(
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
new file mode 100644
index 00000000000..15ea27a4462
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -0,0 +1,53 @@
+//===--- ProBoundsPointerArithmeticCheck.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 "ProBoundsPointerArithmeticCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
+ Finder->addMatcher(
+ binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
+ hasOperatorName("+="), hasOperatorName("-=")),
+ hasType(pointerType()))
+ .bind("expr"),
+ this);
+
+ Finder->addMatcher(
+ unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
+ hasType(pointerType()))
+ .bind("expr"),
+ this);
+
+ // Array subscript on a pointer (not an array) is also pointer arithmetic
+ Finder->addMatcher(
+ arraySubscriptExpr(hasBase(ignoringImpCasts(anyOf(hasType(pointerType()),
+ hasType(decayedType(hasDecayedType(pointerType())))))))
+ .bind("expr"),
+ this);
+}
+
+void
+ProBoundsPointerArithmeticCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedExpr = Result.Nodes.getNodeAs<Expr>("expr");
+
+ diag(MatchedExpr->getExprLoc(), "do not use pointer arithmetic");
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
new file mode 100644
index 00000000000..f3a3fb18cff
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -0,0 +1,34 @@
+//===--- ProBoundsPointerArithmeticCheck.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_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Flags all kinds of pointer arithmetic that have result of pointer type, i.e.
+/// +, -, +=, -=, ++, --. In addition, the [] operator on pointers (not on arrays) is flagged.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.html
+class ProBoundsPointerArithmeticCheck : public ClangTidyCheck {
+public:
+ ProBoundsPointerArithmeticCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
new file mode 100644
index 00000000000..60582eb73eb
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-bounds-pointer-arithmetic
+===============================================
+
+This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer.
+Subtraction of two pointers is not flagged by this check.
+
+Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index c46a7960cd0..c5496361532 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@ List of clang-tidy Checks
.. toctree::
cert-setlongjmp
cert-variadic-function-def
+ cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-const-cast
cppcoreguidelines-pro-type-reinterpret-cast
cppcoreguidelines-pro-type-static-cast-downcast
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
new file mode 100644
index 00000000000..b765f00bd37
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,87 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+enum E {
+ ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int *p = 0;
+int *q = 0;
+
+void fail() {
+ q = p + 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+ p = q + i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q + ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+ q = p - 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q - i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+ p = q - ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+ p += 4;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ p += i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ p += ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+ q -= 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ q -= i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+ q -= ENUM_LITERAL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+ p++;
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+ ++p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+ p--;
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+ --p;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+ i = p[1];
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+ operator int() const;
+};
+
+void f(S &s) {
+ int *i;
+ i = i + s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void f2(int i[]) {
+ i[1] = 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+}
+
+void okay() {
+ int a[3];
+ i = a[2]; // OK, access to array
+
+ p = q;
+ p = &i;
+
+ i++;
+ ++i;
+ i--;
+ --i;
+ i += 1;
+ i -= 1;
+ i = j + 1;
+ i = j - 1;
+
+ auto diff = p - q; // OK, result is arithmetic
+}
OpenPOWER on IntegriCloud