brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 057ab3b Raw
208 lines · cpp
1// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t2 3typedef __SIZE_TYPE__ size_t;4 5namespace std {6  template<typename T, size_t N>7  struct array {8    T& operator[](size_t n);9    T& at(size_t n);10  };11}12 13 14namespace gsl {15  template<class T, size_t N>16  T& at( T(&a)[N], size_t index );17 18  template<class T, size_t N>19  T& at( std::array<T, N> &a, size_t index );20}21 22constexpr int const_index(int base) {23  return base + 3;24}25 26template<class T, size_t N>27class DerivedArray : public std::array<T, N> {};28 29void f(std::array<int, 10> a, int pos) {30  a [ pos / 2 /*comment*/] = 1;31  // 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]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 expression34 35  a.at(pos-1) = 2; // OK, at() instead of []36  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []37 38  a[-1] = 3;39  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]40  a[10] = 4;41  // 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]42 43  a[const_index(7)] = 3;44  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)45 46  a[0] = 3; // OK, constant index and inside bounds47  a[1] = 3; // OK, constant index and inside bounds48  a[9] = 3; // OK, constant index and inside bounds49  a[const_index(6)] = 3; // OK, constant index and inside bounds50 51  using MyArray = std::array<int, 10>;52  MyArray m{};53  m [ pos / 2 /*comment*/] = 1;54  // 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]55  int jj = m[pos - 1];56  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use array subscript when the index is not an integer constant expression57 58  m.at(pos-1) = 2; // OK, at() instead of []59  gsl::at(m, pos-1) = 2; // OK, gsl::at() instead of []60  m[-1] = 3;61  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]62  m[10] = 4;63  // 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]64 65  m[const_index(7)] = 3;66  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)67 68  m[0] = 3; // OK, constant index and inside bounds69  m[1] = 3; // OK, constant index and inside bounds70  m[9] = 3; // OK, constant index and inside bounds71  m[const_index(6)] = 3; // OK, constant index and inside bounds72}73 74template<class T, size_t N>75class PrivateDerivedArray : std::array<T, N> {76public: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 85void 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 expression90 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 bounds103  a[1] = 3; // OK, constant index and inside bounds104  a[9] = 3; // OK, constant index and inside bounds105  a[const_index(6)] = 3; // OK, constant index and inside bounds106 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 expression113 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 bounds125  m[1] = 3; // OK, constant index and inside bounds126  m[9] = 3; // OK, constant index and inside bounds127  m[const_index(6)] = 3; // OK, constant index and inside bounds128 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 bounds141  pm[1] = 3; // OK, constant index and inside bounds142  pm[9] = 3; // OK, constant index and inside bounds143  pm[const_index(6)] = 3; // OK, constant index and inside bounds144}145 146 147 148 149void g() {150  int a[10];151  for (int i = 0; i < 10; ++i) {152    a[i] = i;153    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression154    gsl::at(a, i) = i; // OK, gsl::at() instead of []155  }156 157  a[-1] = 3; // flagged by clang-diagnostic-array-bounds158  a[10] = 4; // flagged by clang-diagnostic-array-bounds159  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds160 161  a[0] = 3; // OK, constant index and inside bounds162  a[1] = 3; // OK, constant index and inside bounds163  a[9] = 3; // OK, constant index and inside bounds164  a[const_index(6)] = 3; // OK, constant index and inside bounds165}166 167struct S {168  int& operator[](int i);169};170 171void customOperator() {172  S s;173  int i = 0;174  s[i] = 3; // OK, custom operator175}176 177namespace ArrayInitIndexExpr {178struct A {179  // The compiler-generated copy constructor uses an ArraySubscriptExpr. Don't warn.180  int x[3];181};182 183void implicitCopyMoveCtor() {184  // Force the compiler to generate a copy constructor.185  A a;186  A a2(a);187 188  // Force the compiler to generate a move constructor.189  A a3 = (A&&) a;190}191 192void lambdaCapture() {193  int arr[3];194 195  // Capturing an array by value uses an ArraySubscriptExpr. Don't warn. 196  [arr](){};197}198 199#if __cplusplus >= 201703L200void structuredBindings() {201  int arr[3];202 203  // Creating structured bindings by value uses an ArraySubscriptExpr. Don't warn.204  auto [a,b,c] = arr;205}206#endif207} // namespace ArrayInitIndexExpr208