Skip to content

Commit d176aa3

Browse files
author
juanbesa
committed
Copied over everything
1 parent ad20dc0 commit d176aa3

File tree

3 files changed

+258
-1
lines changed

3 files changed

+258
-1
lines changed

clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,14 @@ QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
106106
: ClangTidyCheck(Name, Context),
107107
AddConstToQualified(Options.get("AddConstToQualified", true)),
108108
AllowedTypes(
109-
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
109+
utils::options::parseStringList(Options.get("AllowedTypes", ""))),
110+
RespectOpaqueTypes(Options.get("RespectOpaqueTypes", false)) {}
110111

111112
void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
112113
Options.store(Opts, "AddConstToQualified", AddConstToQualified);
113114
Options.store(Opts, "AllowedTypes",
114115
utils::options::serializeStringList(AllowedTypes));
116+
Options.store(Opts, "RespectOpaqueTypes", RespectOpaqueTypes);
115117
}
116118

117119
void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
@@ -174,6 +176,21 @@ void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
174176

175177
void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
176178
if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
179+
if (RespectOpaqueTypes) {
180+
auto DeducedType =
181+
Var->getType()->getContainedAutoType()->getDeducedType();
182+
183+
// Remove one sugar if the type if part of a template
184+
if (llvm::isa<SubstTemplateTypeParmType>(DeducedType)) {
185+
DeducedType =
186+
DeducedType->getLocallyUnqualifiedSingleStepDesugaredType();
187+
}
188+
189+
if (!isa<PointerType>(DeducedType)) {
190+
return;
191+
}
192+
}
193+
177194
SourceRange TypeSpecifier;
178195
if (std::optional<SourceRange> TypeSpec =
179196
getTypeSpecifierLocation(Var, Result)) {

clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class QualifiedAutoCheck : public ClangTidyCheck {
3232
private:
3333
const bool AddConstToQualified;
3434
const std::vector<StringRef> AllowedTypes;
35+
const bool RespectOpaqueTypes;
3536
};
3637

3738
} // namespace clang::tidy::readability
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// RUN: %check_clang_tidy %s readability-qualified-auto %t -- -config="{CheckOptions: [\
2+
// RUN: {key: readability-qualified-auto.RespectOpaqueTypes, value: true}]}" --
3+
4+
namespace typedefs {
5+
typedef int *MyPtr;
6+
typedef int &MyRef;
7+
typedef const int *CMyPtr;
8+
typedef const int &CMyRef;
9+
10+
MyPtr getPtr();
11+
MyPtr* getPtrPtr();
12+
MyRef getRef();
13+
CMyPtr getCPtr();
14+
CMyPtr* getCPtrPtr();
15+
CMyRef getCRef();
16+
int* getIntPtr();
17+
18+
void foo() {
19+
auto TdNakedPtr = getPtr();
20+
auto TdNakedPtrPtr = getPtrPtr();
21+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto TdNakedPtrPtr' can be declared as 'auto *TdNakedPtrPtr'
22+
// CHECK-FIXES: {{^}} auto *TdNakedPtrPtr = getPtrPtr();
23+
auto intPtr = getIntPtr();
24+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto intPtr' can be declared as 'auto *intPtr'
25+
// CHECK-FIXES: {{^}} auto *intPtr = getIntPtr();
26+
auto TdNakedRefDeref = getRef();
27+
auto TdNakedCPtr = getCPtr();
28+
auto TdNakedCPtrPtr = getCPtrPtr();
29+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto TdNakedCPtrPtr' can be declared as 'auto *TdNakedCPtrPtr'
30+
// CHECK-FIXES: {{^}} auto *TdNakedCPtrPtr = getCPtrPtr();
31+
auto &TdNakedCRef = getCRef();
32+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &TdNakedCRef' can be declared as 'const auto &TdNakedCRef'
33+
// CHECK-FIXES: {{^}} const auto &TdNakedCRef = getCRef();
34+
auto TdNakedCRefDeref = getCRef();
35+
}
36+
37+
}; // namespace typedefs
38+
39+
namespace usings {
40+
using MyPtr = int *;
41+
using MyRef = int &;
42+
using CMyPtr = const int *;
43+
using CMyRef = const int &;
44+
45+
MyPtr getPtr();
46+
MyPtr* getPtrPtr();
47+
MyRef getRef();
48+
CMyPtr getCPtr();
49+
CMyRef getCRef();
50+
51+
void foo() {
52+
auto UNakedPtr = getPtr();
53+
auto UNakedPtrPtr = getPtrPtr();
54+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto UNakedPtrPtr' can be declared as 'auto *UNakedPtrPtr'
55+
// CHECK-FIXES: {{^}} auto *UNakedPtrPtr = getPtrPtr();
56+
auto &UNakedRef = getRef();
57+
auto UNakedRefDeref = getRef();
58+
auto UNakedCPtr = getCPtr();
59+
auto &UNakedCRef = getCRef();
60+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &UNakedCRef' can be declared as 'const auto &UNakedCRef'
61+
// CHECK-FIXES: {{^}} const auto &UNakedCRef = getCRef();
62+
auto UNakedCRefDeref = getCRef();
63+
}
64+
65+
}; // namespace usings
66+
67+
int *getIntPtr();
68+
const int *getCIntPtr();
69+
70+
void foo() {
71+
// make sure check disregards named types
72+
int *TypedPtr = getIntPtr();
73+
const int *TypedConstPtr = getCIntPtr();
74+
int &TypedRef = *getIntPtr();
75+
const int &TypedConstRef = *getCIntPtr();
76+
77+
auto NakedPtr = getIntPtr();
78+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedPtr' can be declared as 'auto *NakedPtr'
79+
// CHECK-FIXES: {{^}} auto *NakedPtr = getIntPtr();
80+
auto NakedCPtr = getCIntPtr();
81+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedCPtr' can be declared as 'const auto *NakedCPtr'
82+
// CHECK-FIXES: {{^}} const auto *NakedCPtr = getCIntPtr();
83+
84+
const auto ConstPtr = getIntPtr();
85+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'const auto ConstPtr' can be declared as 'auto *const ConstPtr'
86+
// CHECK-FIXES: {{^}} auto *const ConstPtr = getIntPtr();
87+
const auto ConstCPtr = getCIntPtr();
88+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'const auto ConstCPtr' can be declared as 'const auto *const ConstCPtr'
89+
// CHECK-FIXES: {{^}} const auto *const ConstCPtr = getCIntPtr();
90+
91+
volatile auto VolatilePtr = getIntPtr();
92+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'volatile auto VolatilePtr' can be declared as 'auto *volatile VolatilePtr'
93+
// CHECK-FIXES: {{^}} auto *volatile VolatilePtr = getIntPtr();
94+
volatile auto VolatileCPtr = getCIntPtr();
95+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'volatile auto VolatileCPtr' can be declared as 'const auto *volatile VolatileCPtr'
96+
// CHECK-FIXES: {{^}} const auto *volatile VolatileCPtr = getCIntPtr();
97+
98+
auto *QualPtr = getIntPtr();
99+
auto *QualCPtr = getCIntPtr();
100+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *QualCPtr' can be declared as 'const auto *QualCPtr'
101+
// CHECK-FIXES: {{^}} const auto *QualCPtr = getCIntPtr();
102+
auto *const ConstantQualCPtr = getCIntPtr();
103+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *const ConstantQualCPtr' can be declared as 'const auto *const ConstantQualCPtr'
104+
// CHECK-FIXES: {{^}} const auto *const ConstantQualCPtr = getCIntPtr();
105+
auto *volatile VolatileQualCPtr = getCIntPtr();
106+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *volatile VolatileQualCPtr' can be declared as 'const auto *volatile VolatileQualCPtr'
107+
// CHECK-FIXES: {{^}} const auto *volatile VolatileQualCPtr = getCIntPtr();
108+
const auto *ConstQualCPtr = getCIntPtr();
109+
110+
auto &Ref = *getIntPtr();
111+
auto &CRef = *getCIntPtr();
112+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &CRef' can be declared as 'const auto &CRef'
113+
// CHECK-FIXES: {{^}} const auto &CRef = *getCIntPtr();
114+
const auto &ConstCRef = *getCIntPtr();
115+
116+
if (auto X = getCIntPtr()) {
117+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'auto X' can be declared as 'const auto *X'
118+
// CHECK-FIXES: {{^}} if (const auto *X = getCIntPtr()) {
119+
}
120+
}
121+
122+
namespace std {
123+
124+
template <typename T>
125+
class vector { // dummy impl
126+
T _data[1];
127+
128+
public:
129+
T *begin() { return _data; }
130+
const T *begin() const { return _data; }
131+
T *end() { return &_data[1]; }
132+
const T *end() const { return &_data[1]; }
133+
};
134+
135+
136+
} // namespace std
137+
138+
namespace loops {
139+
140+
void change(int &);
141+
void observe(const int &);
142+
143+
void loopRef(std::vector<int> &Mutate, const std::vector<int> &Constant) {
144+
for (auto &Data : Mutate) {
145+
change(Data);
146+
}
147+
for (auto &Data : Constant) {
148+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto &Data' can be declared as 'const auto &Data'
149+
// CHECK-FIXES: {{^}} for (const auto &Data : Constant) {
150+
observe(Data);
151+
}
152+
}
153+
154+
void loopPtr(const std::vector<int *> &Mutate, const std::vector<const int *> &Constant) {
155+
for (auto Data : Mutate) {
156+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'auto *Data'
157+
// CHECK-FIXES: {{^}} for (auto *Data : Mutate) {
158+
change(*Data);
159+
}
160+
for (auto Data : Constant) {
161+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'const auto *Data'
162+
// CHECK-FIXES: {{^}} for (const auto *Data : Constant) {
163+
observe(*Data);
164+
}
165+
}
166+
167+
template <typename T>
168+
void tempLoopPtr(std::vector<T *> &MutateTemplate, std::vector<const T *> &ConstantTemplate) {
169+
for (auto Data : MutateTemplate) {
170+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'auto *Data'
171+
// CHECK-FIXES: {{^}} for (auto *Data : MutateTemplate) {
172+
change(*Data);
173+
}
174+
//FixMe
175+
for (auto Data : ConstantTemplate) {
176+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'const auto *Data'
177+
// CHECK-FIXES: {{^}} for (const auto *Data : ConstantTemplate) {
178+
observe(*Data);
179+
}
180+
}
181+
182+
template <typename T>
183+
class TemplateLoopPtr {
184+
public:
185+
void operator()(const std::vector<T *> &MClassTemplate, const std::vector<const T *> &CClassTemplate) {
186+
for (auto Data : MClassTemplate) {
187+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'auto Data' can be declared as 'auto *Data'
188+
// CHECK-FIXES: {{^}} for (auto *Data : MClassTemplate) {
189+
change(*Data);
190+
}
191+
//FixMe
192+
for (auto Data : CClassTemplate) {
193+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'auto Data' can be declared as 'const auto *Data'
194+
// CHECK-FIXES: {{^}} for (const auto *Data : CClassTemplate) {
195+
observe(*Data);
196+
}
197+
}
198+
};
199+
200+
void bar() {
201+
std::vector<int> Vec;
202+
std::vector<int *> PtrVec;
203+
std::vector<const int *> CPtrVec;
204+
loopRef(Vec, Vec);
205+
loopPtr(PtrVec, CPtrVec);
206+
tempLoopPtr(PtrVec, CPtrVec);
207+
TemplateLoopPtr<int>()(PtrVec, CPtrVec);
208+
}
209+
210+
typedef int *(*functionRetPtr)();
211+
typedef int (*functionRetVal)();
212+
213+
functionRetPtr getPtrFunction();
214+
functionRetVal getValFunction();
215+
216+
void baz() {
217+
auto MyFunctionPtr = getPtrFunction();
218+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionPtr' can be declared as 'auto *MyFunctionPtr'
219+
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionPtr = getPtrFunction();
220+
auto MyFunctionVal = getValFunction();
221+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionVal' can be declared as 'auto *MyFunctionVal'
222+
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionVal = getValFunction();
223+
224+
auto LambdaTest = [] { return 0; };
225+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto LambdaTest' can be declared as 'auto *LambdaTest'
226+
// CHECK-FIXES-NOT: {{^}} auto *LambdaTest = [] { return 0; };
227+
228+
auto LambdaTest2 = +[] { return 0; };
229+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto LambdaTest2' can be declared as 'auto *LambdaTest2'
230+
// CHECK-FIXES-NOT: {{^}} auto *LambdaTest2 = +[] { return 0; };
231+
232+
auto MyFunctionRef = *getPtrFunction();
233+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionRef' can be declared as 'auto *MyFunctionRef'
234+
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionRef = *getPtrFunction();
235+
236+
auto &MyFunctionRef2 = *getPtrFunction();
237+
}
238+
239+
} // namespace loops

0 commit comments

Comments
 (0)