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