mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.

Inside a range-based for-loop over an array, the compiler
generates pointer arithmetic (end = array + size). Don't flag this.

http://reviews.llvm.org/D14582

Files:
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===================================================================
--- test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===================================================================
--- clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -16,15 +16,28 @@
 namespace clang {
 namespace tidy {
 
+AST_MATCHER_P(CXXForRangeStmt, hasRangeBeginEndStmt,
+              ast_matchers::internal::Matcher<DeclStmt>, InnerMatcher) {
+  const DeclStmt *const Stmt = Node.getBeginEndStmt();
+  return (Stmt != nullptr && InnerMatcher.matches(*Stmt, Finder, Builder));
+}
+
+AST_MATCHER(Stmt, isInsideOfRangeBeginEndStmt) {
+  return stmt(hasAncestor(cxxForRangeStmt(
+                  hasRangeBeginEndStmt(hasDescendant(equalsNode(&Node))))))
+      .matches(Node, Finder, Builder);
+}
+
 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()))
+                     hasType(pointerType()),
+                     unless(isInsideOfRangeBeginEndStmt()))
           .bind("expr"),
       this);
 


Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===================================================================
--- test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===================================================================
--- clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -16,15 +16,28 @@
 namespace clang {
 namespace tidy {
 
+AST_MATCHER_P(CXXForRangeStmt, hasRangeBeginEndStmt,
+              ast_matchers::internal::Matcher<DeclStmt>, InnerMatcher) {
+  const DeclStmt *const Stmt = Node.getBeginEndStmt();
+  return (Stmt != nullptr && InnerMatcher.matches(*Stmt, Finder, Builder));
+}
+
+AST_MATCHER(Stmt, isInsideOfRangeBeginEndStmt) {
+  return stmt(hasAncestor(cxxForRangeStmt(
+                  hasRangeBeginEndStmt(hasDescendant(equalsNode(&Node))))))
+      .matches(Node, Finder, Builder);
+}
+
 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()))
+                     hasType(pointerType()),
+                     unless(isInsideOfRangeBeginEndStmt()))
           .bind("expr"),
       this);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to