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

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.
This commit is contained in:
flovent
2025-07-02 22:41:24 +08:00
committed by GitHub
parent cbfd0d68ea
commit 5a8d096ae3
3 changed files with 29 additions and 1 deletions

View File

@@ -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);
}

View File

@@ -216,6 +216,11 @@ Changes in existing checks
<clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a
flag to specify the function used for forwarding instead of ``std::forward``.
- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
<clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
fixing false positives when calling indexing operators that do not perform
pointer arithmetic in template, for example ``std::map::operator[]``.
- Improved :doc:`cppcoreguidelines-rvalue-reference-param-not-moved
<clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved>` check
by adding a flag to specify the function used for moving instead of

View File

@@ -87,3 +87,25 @@ void okay() {
for(int ii : a) ; // OK, pointer arithmetic generated by compiler
}
namespace gh126424 {
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
}
}