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 24 constexpr int const_index(int base) { 25 return base + 3; 26 } 27 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 [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 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 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 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 76 void customOperator() { 77 S s; 78 int i = 0; 79 s[i] = 3; // OK, custom operator 80 } 81