cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp 2.72 KB
Newer Older
1
2
// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- \
// RUN:     -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}'
3
4
// CHECK-FIXES: #include "dir1/gslheader.h"

5
typedef __SIZE_TYPE__ size_t;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

namespace std {
  template<typename T, size_t N>
  struct array {
    T& operator[](size_t n);
    T& at(size_t n);
  };
}


namespace gsl {
  template<class T, size_t N>
  T& at( T(&a)[N], size_t index );

  template<class T, size_t N>
  T& at( std::array<T, N> &a, size_t index );
}

constexpr int const_index(int base) {
  return base + 3;
}

void f(std::array<int, 10> a, int pos) {
  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
32
  // CHECK-FIXES: gsl::at(a,  pos / 2 /*comment*/) = 1;
  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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  // CHECK-FIXES: int j = gsl::at(a, pos - 1);

  a.at(pos-1) = 2; // OK, at() instead of []
  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []

  a[-1] = 3;
  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
  a[10] = 4;
  // 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]

  a[const_index(7)] = 3;
  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)

  a[0] = 3; // OK, constant index and inside bounds
  a[1] = 3; // OK, constant index and inside bounds
  a[9] = 3; // OK, constant index and inside bounds
  a[const_index(6)] = 3; // OK, constant index and inside bounds
}

void g() {
  int a[10];
  for (int i = 0; i < 10; ++i) {
    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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    // CHECK-FIXES: gsl::at(a, i) = i;
    gsl::at(a, i) = i; // OK, gsl::at() instead of []
  }

  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
  a[10] = 4; // flagged by clang-diagnostic-array-bounds
  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds

  a[0] = 3; // OK, constant index and inside bounds
  a[1] = 3; // OK, constant index and inside bounds
  a[9] = 3; // OK, constant index and inside bounds
  a[const_index(6)] = 3; // OK, constant index and inside bounds
}

struct S {
  int& operator[](int i);
};

void customOperator() {
  S s;
  int i = 0;
  s[i] = 3; // OK, custom operator
}