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