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