1 | // RUN: %check_clang_tidy %s misc-const-correctness %t \ |
2 | // RUN: -config='{CheckOptions: \ |
3 | // RUN: {misc-const-correctness.AnalyzeValues: true,\ |
4 | // RUN: misc-const-correctness.WarnPointersAsValues: true,\ |
5 | // RUN: misc-const-correctness.TransformPointersAsValues: true}}' \ |
6 | // RUN: -- -fno-delayed-template-parsing |
7 | |
8 | void potential_const_pointer() { |
9 | double np_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; |
10 | double *p_local0 = &np_local0[1]; |
11 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double *' can be declared 'const' |
12 | // CHECK-FIXES: double *const p_local0 |
13 | |
14 | using doublePtr = double*; |
15 | using doubleArray = double[15]; |
16 | doubleArray np_local1; |
17 | doublePtr p_local1 = &np_local1[0]; |
18 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'doublePtr' (aka 'double *') can be declared 'const' |
19 | // CHECK-FIXES: doublePtr const p_local1 |
20 | } |
21 | |
22 | void range_for() { |
23 | int np_local0[2] = {1, 2}; |
24 | int *p_local0[2] = {&np_local0[0], &np_local0[1]}; |
25 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[2]' can be declared 'const' |
26 | // CHECK-FIXES: int *const p_local0[2] |
27 | for (const int *p_local1 : p_local0) { |
28 | // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'const int *' can be declared 'const' |
29 | // CHECK-FIXES: for (const int *const p_local1 : p_local0) |
30 | } |
31 | |
32 | int *p_local2[2] = {nullptr, nullptr}; |
33 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const' |
34 | // CHECK-FIXES: int *const p_local2[2] |
35 | for (const auto *con_ptr : p_local2) { |
36 | } |
37 | |
38 | } |
39 | |
40 | template <typename T> |
41 | struct SmallVectorBase { |
42 | T data[4]; |
43 | void push_back(const T &el) {} |
44 | int size() const { return 4; } |
45 | T *begin() { return data; } |
46 | const T *begin() const { return data; } |
47 | T *end() { return data + 4; } |
48 | const T *end() const { return data + 4; } |
49 | }; |
50 | |
51 | template <typename T> |
52 | struct SmallVector : SmallVectorBase<T> {}; |
53 | |
54 | template <class T> |
55 | void EmitProtocolMethodList(T &&Methods) { |
56 | // Note: If the template is uninstantiated the analysis does not figure out, |
57 | // that p_local0 could be const. Not sure why, but probably bails because |
58 | // some expressions are type-dependent. |
59 | SmallVector<const int *> p_local0; |
60 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const' |
61 | // CHECK-FIXES: SmallVector<const int *> const p_local0 |
62 | SmallVector<const int *> np_local0; |
63 | for (const auto *I : Methods) { |
64 | if (I == nullptr) |
65 | np_local0.push_back(el: I); |
66 | } |
67 | p_local0.size(); |
68 | } |
69 | void instantiate() { |
70 | int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; |
71 | // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const' |
72 | // CHECK-FIXES: int *const p_local0[4] |
73 | EmitProtocolMethodList(Methods&: p_local0); |
74 | } |
75 | |