1 // RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- \
2 // RUN: -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}'
3 // CHECK-FIXES: #include "dir1/gslheader.h"
4
5 typedef __SIZE_TYPE__ size_t;
6
7 namespace std {
8 template<typename T, size_t N>
9 struct array {
10 T& operator[](size_t n);
11 T& at(size_t n);
12 };
13 }
14
15
16 namespace gsl {
17 template<class T, size_t N>
18 T& at( T(&a)[N], size_t index );
19
20 template<class T, size_t N>
21 T& at( std::array<T, N> &a, size_t index );
22 }
23
const_index(int base)24 constexpr int const_index(int base) {
25 return base + 3;
26 }
27
f(std::array<int,10> a,int pos)28 void f(std::array<int, 10> a, int pos) {
29 a [ pos / 2 /*comment*/] = 1;
30 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
31 // CHECK-FIXES: gsl::at(a, pos / 2 /*comment*/) = 1;
32 int j = a[pos - 1];
33 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
34 // CHECK-FIXES: int j = gsl::at(a, pos - 1);
35
36 a.at(pos-1) = 2; // OK, at() instead of []
37 gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
38
39 a[-1] = 3;
40 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
41 a[10] = 4;
42 // 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]
43
44 a[const_index(7)] = 3;
45 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
46
47 a[0] = 3; // OK, constant index and inside bounds
48 a[1] = 3; // OK, constant index and inside bounds
49 a[9] = 3; // OK, constant index and inside bounds
50 a[const_index(6)] = 3; // OK, constant index and inside bounds
51 }
52
g()53 void g() {
54 int a[10];
55 for (int i = 0; i < 10; ++i) {
56 a[i] = i;
57 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
58 // CHECK-FIXES: gsl::at(a, i) = i;
59 gsl::at(a, i) = i; // OK, gsl::at() instead of []
60 }
61
62 a[-1] = 3; // flagged by clang-diagnostic-array-bounds
63 a[10] = 4; // flagged by clang-diagnostic-array-bounds
64 a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
65
66 a[0] = 3; // OK, constant index and inside bounds
67 a[1] = 3; // OK, constant index and inside bounds
68 a[9] = 3; // OK, constant index and inside bounds
69 a[const_index(6)] = 3; // OK, constant index and inside bounds
70 }
71
72 struct S {
73 int& operator[](int i);
74 };
75
customOperator()76 void customOperator() {
77 S s;
78 int i = 0;
79 s[i] = 3; // OK, custom operator
80 }
81