Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[clang-tidy] Fix false positive for cppcoreguidelines-pro-bounds-pointer-arithmetic #127394

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

flovent
Copy link
Contributor

@flovent flovent commented Feb 16, 2025

this PR fixes #126424
for ArraySubScriptExpr, hasBase Matcher will get right operand when it is not integer type, but is not for sure that left operand is integer type. For the example code below hasBase will get r for the Subsequent matching and causing false positive.

template <typename R>
int f(std::map<R*, int>& map, R* r) {
  return map[r];
}

so is needed to see if index is integer type to avoid this situation.

@llvmbot
Copy link
Member

llvmbot commented Feb 16, 2025

@llvm/pr-subscribers-clang-tidy

Author: None (flovent)

Changes

this PR fixs #126424
for ArraySubScriptExpr, hasBase Matcher will get right operand when it is not Integer type, but is not for sure that left operand is interger type. For the example code below hasBase will get r for the Subsequent matching and causing false positive.

template &lt;typename R&gt;
int f(std::map&lt;R*, int&gt;&amp; map, R* r) {
  return map[r];
}

so is needed to see if index is interger type to avoid this situation.


Full diff: https://github.com/llvm/llvm-project/pull/127394.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp (+2-1)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (added) clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp (+19)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
index a1494a095f5b6..0d68790349fb5 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -42,7 +42,8 @@ void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
       arraySubscriptExpr(
           hasBase(ignoringImpCasts(
               anyOf(AllPointerTypes,
-                    hasType(decayedType(hasDecayedType(pointerType())))))))
+                    hasType(decayedType(hasDecayedType(pointerType())))))),
+          hasIndex(hasType(isInteger())))
           .bind("expr"),
       this);
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6b8fe22242417..937d710fe6100 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -110,6 +110,10 @@ Changes in existing checks
   <clang-tidy/checks/misc/redundant-expression>` check by providing additional
   examples and fixing some macro related false positives.
 
+- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
+  <clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
+  fix false positives related to operator overloading and templates.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp
new file mode 100644
index 0000000000000..b6b7a9664f38d
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+namespace std {
+template <typename, typename>
+class pair {};
+
+template <typename Key, typename Value>
+class map {
+  public:
+   using value_type = pair<Key, Value>;
+   value_type& operator[](const Key& key);
+   value_type& operator[](Key&& key);
+ };
+}
+
+template <typename R>
+int f(std::map<R*, int>& map, R* r) {
+  return map[r]; // OK
+}
\ No newline at end of file

@llvmbot
Copy link
Member

llvmbot commented Feb 16, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: None (flovent)

Changes

this PR fixs #126424
for ArraySubScriptExpr, hasBase Matcher will get right operand when it is not Integer type, but is not for sure that left operand is interger type. For the example code below hasBase will get r for the Subsequent matching and causing false positive.

template &lt;typename R&gt;
int f(std::map&lt;R*, int&gt;&amp; map, R* r) {
  return map[r];
}

so is needed to see if index is interger type to avoid this situation.


Full diff: https://github.com/llvm/llvm-project/pull/127394.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp (+2-1)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (added) clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp (+19)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
index a1494a095f5b6..0d68790349fb5 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -42,7 +42,8 @@ void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
       arraySubscriptExpr(
           hasBase(ignoringImpCasts(
               anyOf(AllPointerTypes,
-                    hasType(decayedType(hasDecayedType(pointerType())))))))
+                    hasType(decayedType(hasDecayedType(pointerType())))))),
+          hasIndex(hasType(isInteger())))
           .bind("expr"),
       this);
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6b8fe22242417..937d710fe6100 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -110,6 +110,10 @@ Changes in existing checks
   <clang-tidy/checks/misc/redundant-expression>` check by providing additional
   examples and fixing some macro related false positives.
 
+- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
+  <clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
+  fix false positives related to operator overloading and templates.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp
new file mode 100644
index 0000000000000..b6b7a9664f38d
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+namespace std {
+template <typename, typename>
+class pair {};
+
+template <typename Key, typename Value>
+class map {
+  public:
+   using value_type = pair<Key, Value>;
+   value_type& operator[](const Key& key);
+   value_type& operator[](Key&& key);
+ };
+}
+
+template <typename R>
+int f(std::map<R*, int>& map, R* r) {
+  return map[r]; // OK
+}
\ No newline at end of file

@flovent
Copy link
Contributor Author

flovent commented Feb 24, 2025

ping

@carlosgalvezp
Copy link
Contributor

LGTM in general, but won't this fail with a std::map<int, int>, since the key is an integer?

Please rebase on top of latest main and resolve conflicts.

@@ -106,6 +106,10 @@ Changes in existing checks
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
additional C++ member functions to match.

- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
<clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
fix false positives related to operator overloading and templates.
Copy link
Contributor

@carlosgalvezp carlosgalvezp Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"by fixing"

Also, "operator overloading and templates" seems too generic, maybe "when calling indexing operators that do not perform pointer arithmetic, for example std::map::operator[]"?

Copy link
Contributor Author

@flovent flovent May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think template should be mentioned because it's the necessary condition in this false positive, for std::map::operator[] or other indexing operators like std::vector::operator[] outside of template, there will be CallExpr generated, this checker didn't match CallExpr before this PR's change.

Using indexing operator does make it more specific, since ArraySubScriptExpr only shows for this kind of overload operator.

Maybe "by fixing false positives when calling indexing operators that do not perform pointer arithmetic in template, for example std::map::operator[]"?

@flovent
Copy link
Contributor Author

flovent commented May 1, 2025

but won't this fail with a std::map<int, int>, since the key is an integer?

It won't, ArraySubScriptExpr is generated here because variable map's type is dependent, it's AST:

ArraySubscriptExpr <col:10, col:15> '<dependent type>' lvalue
      -DeclRefExpr <col:10> 'std::map<R *, int>':'map<R *, int>' lvalue ParmVar 0x227b3b48 'map' 'std::map<R *, int> &'
      -DeclRefExpr <col:14> 'R *' lvalue ParmVar 0x227b3bc8 'r' 'R *'

std::map's key is unrelated here, for std::map<int, int> a CallExpr will be generated since it's known that std::map<int, int> has a overload operator []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants