Skip to content

Commit 41818ce

Browse files
sousajo-ccPiotrZSL
authored andcommitted
[clang-tidy] Access checks not done classes derived of std::array
Index accessing checks are not performed for derived classes of of `std::array`, as only `std::array` itself and its aliases seems to be checked. This patch aims to extend it for derived classes such as: ``` template<class T, size_t N> class DerivedArray : public std::array<T, N> {}; ``` Reviewed By: PiotrZSL Differential Revision: https://reviews.llvm.org/D156624
1 parent e9e4584 commit 41818ce

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
4848
Finder->addMatcher(
4949
cxxOperatorCallExpr(
5050
hasOverloadedOperatorName("[]"),
51-
hasArgument(
52-
0, hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
53-
cxxRecordDecl(hasName("::std::array")).bind("type")))))),
51+
callee(cxxMethodDecl(
52+
ofClass(cxxRecordDecl(hasName("::std::array")).bind("type")))),
5453
hasArgument(1, expr().bind("index")))
5554
.bind("expr"),
5655
this);

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ Changes in existing checks
202202
<clang-tidy/checks/cppcoreguidelines/pro-bounds-array-to-pointer-decay>` check
203203
to ignore predefined expression (e.g., ``__func__``, ...).
204204

205+
- Improved :doc:`cppcoreguidelines-pro-bounds-constant-array-index
206+
<clang-tidy/checks/cppcoreguidelines/pro-bounds-constant-array-index>` check
207+
to perform checks on derived classes of ``std::array``.
208+
205209
- Improved :doc:`cppcoreguidelines-pro-type-member-init
206210
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check to ignore
207211
dependent delegate constructors.

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ constexpr int const_index(int base) {
2323
return base + 3;
2424
}
2525

26+
template<class T, size_t N>
27+
class DerivedArray : public std::array<T, N> {};
28+
2629
void f(std::array<int, 10> a, int pos) {
2730
a [ pos / 2 /*comment*/] = 1;
2831
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]
@@ -68,6 +71,81 @@ void f(std::array<int, 10> a, int pos) {
6871
m[const_index(6)] = 3; // OK, constant index and inside bounds
6972
}
7073

74+
template<class T, size_t N>
75+
class PrivateDerivedArray : std::array<T, N> {
76+
public:
77+
T& operator[](size_t n){
78+
return std::array<T, N>::operator[](static_cast<int>(n));
79+
};
80+
T& at(size_t n) {
81+
return std::array<T, N>::at(static_cast<int>(n));
82+
};
83+
};
84+
85+
void f_derived(DerivedArray<int, 10> a, int pos) {
86+
a [ pos / 2 /*comment*/] = 1;
87+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]
88+
int j = a[pos - 1];
89+
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression
90+
91+
a.at(pos-1) = 2; // OK, at() instead of []
92+
gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
93+
94+
a[-1] = 3;
95+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
96+
a[10] = 4;
97+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
98+
99+
a[const_index(7)] = 3;
100+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
101+
102+
a[0] = 3; // OK, constant index and inside bounds
103+
a[1] = 3; // OK, constant index and inside bounds
104+
a[9] = 3; // OK, constant index and inside bounds
105+
a[const_index(6)] = 3; // OK, constant index and inside bounds
106+
107+
using MyArray = DerivedArray<int, 10>;
108+
MyArray m{};
109+
m [ pos / 2 /*comment*/] = 1;
110+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index]
111+
int jj = m[pos - 1];
112+
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use array subscript when the index is not an integer constant expression
113+
114+
m.at(pos-1) = 2; // OK, at() instead of []
115+
gsl::at(m, pos-1) = 2; // OK, gsl::at() instead of []
116+
m[-1] = 3;
117+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
118+
m[10] = 4;
119+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
120+
121+
m[const_index(7)] = 3;
122+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
123+
124+
m[0] = 3; // OK, constant index and inside bounds
125+
m[1] = 3; // OK, constant index and inside bounds
126+
m[9] = 3; // OK, constant index and inside bounds
127+
m[const_index(6)] = 3; // OK, constant index and inside bounds
128+
129+
using MyPrivateArray = PrivateDerivedArray<int, 10>;
130+
MyPrivateArray pm{};
131+
pm [ pos / 2 /*comment*/] = 1;
132+
int jjj = pm[pos - 1];
133+
134+
pm.at(pos-1) = 2; // OK, at() instead of []
135+
pm[-1] = 3;
136+
pm[10] = 4;
137+
138+
pm[const_index(7)] = 3;
139+
140+
pm[0] = 3; // OK, constant index and inside bounds
141+
pm[1] = 3; // OK, constant index and inside bounds
142+
pm[9] = 3; // OK, constant index and inside bounds
143+
pm[const_index(6)] = 3; // OK, constant index and inside bounds
144+
}
145+
146+
147+
148+
71149
void g() {
72150
int a[10];
73151
for (int i = 0; i < 10; ++i) {

0 commit comments

Comments
 (0)