cppcoreguidelines-pro-bounds-constant-array-index.cpp
2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
typedef __SIZE_TYPE__ size_t;
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;
// 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]
int j = a[pos - 1];
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
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;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
// 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
}
struct A {
// The compiler-generated copy constructor uses an ArraySubscriptExpr. Don't warn.
int x[3];
};
void use_A() {
// Force the compiler to generate a copy constructor.
A a;
A a2(a);
}