- 
                Notifications
    
You must be signed in to change notification settings  - Fork 15.1k
 
          [clang-tidy] fix false negatives with type aliases in cppcoreguidlines-pro-bounds-pointer-arithmetic check
          #139430
        
          New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
  
    [clang-tidy] fix false negatives with type aliases in cppcoreguidlines-pro-bounds-pointer-arithmetic check
  
  #139430
              Conversation
| 
          
 @llvm/pr-subscribers-clang-tools-extra @llvm/pr-subscribers-clang-tidy Author: Baranov Victor (vbvictor) ChangesFixed false negatives with type aliases in  Closes #139241. Full diff: https://github.com/llvm/llvm-project/pull/139430.diff 5 Files Affected: 
 diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
index a1494a095f5b6..4c48fc923fa87 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -15,16 +15,13 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::cppcoreguidelines {
 
 void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
-  if (!getLangOpts().CPlusPlus)
-    return;
-
   const auto AllPointerTypes =
-      anyOf(hasType(pointerType()),
+      anyOf(hasType(hasUnqualifiedDesugaredType(pointerType())),
             hasType(autoType(
                 hasDeducedType(hasUnqualifiedDesugaredType(pointerType())))),
             hasType(decltypeType(hasUnderlyingType(pointerType()))));
 
-  // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
+  // Flag all operators +, -, +=, -= that result in a pointer
   Finder->addMatcher(
       binaryOperator(
           hasAnyOperatorName("+", "-", "+=", "-="), AllPointerTypes,
@@ -32,8 +29,12 @@ void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
           .bind("expr"),
       this);
 
+  // Flag all operators ++, -- that result in a pointer
   Finder->addMatcher(
-      unaryOperator(hasAnyOperatorName("++", "--"), hasType(pointerType()))
+      unaryOperator(hasAnyOperatorName("++", "--"),
+                    hasType(hasUnqualifiedDesugaredType(pointerType())),
+                    unless(hasUnaryOperand(
+                        ignoringImpCasts(declRefExpr(to(isImplicit()))))))
           .bind("expr"),
       this);
 
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
index 67f7d1bf9dd69..3466c72a769e9 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -23,6 +23,9 @@ class ProBoundsPointerArithmeticCheck : public ClangTidyCheck {
 public:
   ProBoundsPointerArithmeticCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus;
+  }
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 579fca54924d5..a19bf190d85f2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -166,6 +166,10 @@ Changes in existing checks
   <clang-tidy/checks/cert/err33-c>` check by fixing false positives when
   a function name is just prefixed with a targeted function name.
 
+- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
+  <clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
+  fixing false negatives when pointer arithmetic was used through type aliases.
+
 - Improved :doc:`misc-const-correctness
   <clang-tidy/checks/misc/const-correctness>` check by adding the option
   `AllowedTypes`, that excludes specified types from const-correctness
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp
index faab2a1ccf0e1..b3d3fab9c5409 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp
@@ -1,11 +1,14 @@
 // RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
 
 // Fix PR36489 and detect auto-deduced value correctly.
+typedef char* charPtr;
+
 char *getPtr();
 auto getPtrAuto() { return getPtr(); }
 decltype(getPtr()) getPtrDeclType();
 decltype(auto) getPtrDeclTypeAuto() { return getPtr(); }
 auto getPtrWithTrailingReturnType() -> char *;
+charPtr getCharPtr() { return getPtr(); }
 
 void auto_deduction_binary() {
   auto p1 = getPtr() + 1;
@@ -28,6 +31,10 @@ void auto_deduction_binary() {
   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not use pointer arithmetic
   auto *p9 = getPtrDeclTypeAuto() + 1;
   // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not use pointer arithmetic
+  auto p10 = getCharPtr() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not use pointer 
+  auto* p11 = getCharPtr() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not use pointer arithmetic
 }
 
 void auto_deduction_subscript() {
@@ -50,4 +57,6 @@ void auto_deduction_subscript() {
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
   auto p8 = getPtrDeclTypeAuto()[9];
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+  auto p9 = getCharPtr()[10];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
 }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp
index 7cbc6ddf96ab6..b1534eeb36827 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp
@@ -4,10 +4,13 @@ enum E {
   ENUM_LITERAL = 1
 };
 
+typedef int* IntPtr;
+
 int i = 4;
 int j = 1;
 int *p = 0;
 int *q = 0;
+IntPtr ip = 0;
 
 void fail() {
   q = p + 4;
@@ -50,6 +53,32 @@ void fail() {
 
   i = p[1];
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+
+  p = ip + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not use pointer arithmetic
+  ip++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  i = ip[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+template <typename T>
+void template_fail() {
+  T* p;
+  T* q;
+
+  p = q + 1;
+  // 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++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+void instantiate() {
+  template_fail<int>();
 }
 
 struct S {
 | 
    
027a49e    to
    5236d19      
    Compare
  
    | 
           rebase + Ping  | 
    
5236d19    to
    8707e40      
    Compare
  
    8707e40    to
    a5e4fbc      
    Compare
  
    | 
           rebased + ping  | 
    
a5e4fbc    to
    9737402      
    Compare
  
    | 
           Ping, changes are quite easy  | 
    
9737402    to
    08ae4bb      
    Compare
  
    
Fixed false negatives with type aliases in
cppcoreguidlines-pro-bounds-pointer-arithmeticcheck.Added tests with pointer arithmetic in template functions to make test cases more robust.
Closes #139241.