Skip to content

Commit e66345d

Browse files
committed
[clang-tidy] adjust treating of array-of-pointers when 'AnalyzePointers' is deactivated
'misc-const-correctness' previously considered arrays as 'Values' independent of the type of the elements. This is inconsistent with the configuration of the check to disable treating pointers as values. This patch rectifies this inconsistency. Fixes #56749 Reviewed By: njames93 Differential Revision: https://reviews.llvm.org/D130793
1 parent 5dcd6af commit e66345d

File tree

3 files changed

+73
-48
lines changed

3 files changed

+73
-48
lines changed

clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
#include "clang/ASTMatchers/ASTMatchFinder.h"
1313
#include "clang/ASTMatchers/ASTMatchers.h"
1414

15-
#include <iostream>
16-
1715
using namespace clang::ast_matchers;
1816

1917
namespace clang {
@@ -132,6 +130,12 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
132130
VC = VariableCategory::Reference;
133131
if (Variable->getType()->isPointerType())
134132
VC = VariableCategory::Pointer;
133+
if (Variable->getType()->isArrayType()) {
134+
if (const auto *ArrayT = dyn_cast<ArrayType>(Variable->getType())) {
135+
if (ArrayT->getElementType()->isPointerType())
136+
VC = VariableCategory::Pointer;
137+
}
138+
}
135139

136140
// Each variable can only be in one category: Value, Pointer, Reference.
137141
// Analysis can be controlled for every category.

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,65 @@ void potential_const_pointer() {
1010
double *p_local0 = &np_local0[1];
1111
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double *' can be declared 'const'
1212
// 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(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(p_local0);
1374
}

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -526,18 +526,13 @@ void range_for() {
526526
// CHECK-FIXES: int const p_local1[2]
527527
for (const int &const_ref : p_local1) {
528528
}
529+
}
529530

530-
int *p_local2[2] = {&np_local0[0], &np_local0[1]};
531-
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const'
532-
// CHECK-FIXES: int *const p_local2[2]
533-
for (const int *con_ptr : p_local2) {
534-
}
535-
536-
int *p_local3[2] = {nullptr, nullptr};
537-
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'int *[2]' can be declared 'const'
538-
// CHECK-FIXES: int *const p_local3[2]
539-
for (const auto *con_ptr : p_local3) {
540-
}
531+
void arrays_of_pointers_are_ignored() {
532+
int *np_local0[2] = {nullptr, nullptr};
533+
534+
using intPtr = int*;
535+
intPtr np_local1[2] = {nullptr, nullptr};
541536
}
542537

543538
inline void *operator new(decltype(sizeof(void *)), void *p) { return p; }
@@ -908,41 +903,6 @@ void vlas() {
908903
sizeof(int[++N]);
909904
}
910905

911-
template <typename T>
912-
struct SmallVectorBase {
913-
T data[4];
914-
void push_back(const T &el) {}
915-
int size() const { return 4; }
916-
T *begin() { return data; }
917-
const T *begin() const { return data; }
918-
T *end() { return data + 4; }
919-
const T *end() const { return data + 4; }
920-
};
921-
922-
template <typename T>
923-
struct SmallVector : SmallVectorBase<T> {};
924-
925-
template <class T>
926-
void EmitProtocolMethodList(T &&Methods) {
927-
// Note: If the template is uninstantiated the analysis does not figure out,
928-
// that p_local0 could be const. Not sure why, but probably bails because
929-
// some expressions are type-dependent.
930-
SmallVector<const int *> p_local0;
931-
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const'
932-
// CHECK-FIXES: SmallVector<const int *> const p_local0
933-
SmallVector<const int *> np_local0;
934-
for (const auto *I : Methods) {
935-
if (I == nullptr)
936-
np_local0.push_back(I);
937-
}
938-
p_local0.size();
939-
}
940-
void instantiate() {
941-
int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr};
942-
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const'
943-
// CHECK-FIXES: int *const p_local0[4]
944-
EmitProtocolMethodList(p_local0);
945-
}
946906
struct base {
947907
int member;
948908
};

0 commit comments

Comments
 (0)