1 // RUN: %check_clang_tidy %s modernize-use-auto %t -- \
2 // RUN: -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
3 // RUN: -- -I %S/Inputs/modernize-use-auto -frtti
4
5 struct A {
~AA6 virtual ~A() {}
7 };
8
9 struct B : public A {};
10
11 struct C {};
12
f_static_cast()13 void f_static_cast() {
14 long l = 1;
15 int i1 = static_cast<int>(l);
16 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
17 // CHECK-FIXES: auto i1 = static_cast<int>(l);
18
19 const int i2 = static_cast<int>(l);
20 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
21 // CHECK-FIXES: const auto i2 = static_cast<int>(l);
22
23 long long ll = static_cast<long long>(l);
24 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
25 // CHECK-FIXES: auto ll = static_cast<long long>(l);
26 unsigned long long ull = static_cast<unsigned long long>(l);
27 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
28 // CHECK-FIXES: auto ull = static_cast<unsigned long long>(l);
29 unsigned int ui = static_cast<unsigned int>(l);
30 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
31 // CHECK-FIXES: auto ui = static_cast<unsigned int>(l);
32 long double ld = static_cast<long double>(l);
33 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
34 // CHECK-FIXES: auto ld = static_cast<long double>(l);
35
36 A *a = new B();
37 B *b1 = static_cast<B *>(a);
38 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
39 // CHECK-FIXES: auto *b1 = static_cast<B *>(a);
40
41 B *const b2 = static_cast<B *>(a);
42 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
43 // CHECK-FIXES: auto *const b2 = static_cast<B *>(a);
44
45 const B *b3 = static_cast<const B *>(a);
46 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
47 // CHECK-FIXES: const auto *b3 = static_cast<const B *>(a);
48
49 B &b4 = static_cast<B &>(*a);
50 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
51 // CHECK-FIXES: auto &b4 = static_cast<B &>(*a);
52
53 const B &b5 = static_cast<const B &>(*a);
54 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
55 // CHECK-FIXES: const auto &b5 = static_cast<const B &>(*a);
56
57 B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
58 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
59 // CHECK-FIXES: auto &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
60
61 // Don't warn when non-cast involved
62 long double cast = static_cast<long double>(l), noncast = 5;
63
64 // Don't warn when auto is already being used.
65 auto i3 = static_cast<int>(l);
66 auto *b8 = static_cast<B *>(a);
67 auto &b9 = static_cast<B &>(*a);
68 }
69
f_dynamic_cast()70 void f_dynamic_cast() {
71 A *a = new B();
72 B *b1 = dynamic_cast<B *>(a);
73 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
74 // CHECK-FIXES: auto *b1 = dynamic_cast<B *>(a);
75
76 B &b2 = dynamic_cast<B &>(*a);
77 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
78 // CHECK-FIXES: auto &b2 = dynamic_cast<B &>(*a);
79 }
80
f_reinterpret_cast()81 void f_reinterpret_cast() {
82 auto *a = new A();
83 C *c1 = reinterpret_cast<C *>(a);
84 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
85 // CHECK-FIXES: auto *c1 = reinterpret_cast<C *>(a);
86
87 C &c2 = reinterpret_cast<C &>(*a);
88 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
89 // CHECK-FIXES: auto &c2 = reinterpret_cast<C &>(*a);
90 }
91
f_const_cast()92 void f_const_cast() {
93 const A *a1 = new A();
94 A *a2 = const_cast<A *>(a1);
95 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
96 // CHECK-FIXES: auto *a2 = const_cast<A *>(a1);
97 A &a3 = const_cast<A &>(*a1);
98 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
99 // CHECK-FIXES: auto &a3 = const_cast<A &>(*a1);
100 }
101
102 typedef unsigned char xmlChar;
103 #define BAD_CAST (xmlChar *)
104
105 #define XMLCHAR_CAST(x) (xmlChar *)(x)
106
107 #define CAST_IN_MACRO(x) \
108 do { \
109 xmlChar *s = (xmlChar *)(x); \
110 } while (false);
111 // CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
112
f_cstyle_cast()113 void f_cstyle_cast() {
114 auto *a = new A();
115 C *c1 = (C *)a;
116 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
117 // CHECK-FIXES: auto *c1 = (C *)a;
118
119 C &c2 = (C &)*a;
120 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
121 // CHECK-FIXES: auto &c2 = (C &)*a;
122
123 xmlChar *s = BAD_CAST "xml";
124 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
125 // CHECK-FIXES: auto *s = BAD_CAST "xml";
126 xmlChar *t = XMLCHAR_CAST("xml");
127 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
128 // CHECK-FIXES: auto *t = XMLCHAR_CAST("xml");
129 CAST_IN_MACRO("xml");
130 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
131 }
132
f_functional_cast()133 void f_functional_cast() {
134 long l = 1;
135 int i1 = int(l);
136 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
137 // CHECK-FIXES: auto i1 = int(l);
138
139 B b;
140 A a = A(b);
141 }
142
143 class StringRef
144 {
145 public:
146 StringRef(const char *);
147 const char *begin() const;
148 const char *end() const;
149 };
150
151 template <typename T, typename U>
152 T template_value_cast(const U &u);
153
154 template <typename T, typename U>
155 T *template_pointer_cast(U *u);
156
157 template <typename T, typename U>
158 T &template_reference_cast(U &u);
159
160 template <typename T, typename U>
161 const T *template_const_pointer_cast(const U *u);
162
163 template <typename T, typename U>
164 const T &template_const_reference_cast(const U &u);
165
166 template <typename T>
167 T template_value_get(StringRef s);
168
169 struct S {
170 template <typename T>
171 const T *template_member_get();
172 };
173
174 template <typename T>
175 T max(T t1, T t2);
176
f_template_cast()177 void f_template_cast()
178 {
179 double d = 0;
180 int i1 = template_value_cast<int>(d);
181 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
182 // CHECK-FIXES: auto i1 = template_value_cast<int>(d);
183
184 A *a = new B();
185 B *b1 = template_value_cast<B *>(a);
186 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
187 // CHECK-FIXES: auto *b1 = template_value_cast<B *>(a);
188 B &b2 = template_value_cast<B &>(*a);
189 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
190 // CHECK-FIXES: auto &b2 = template_value_cast<B &>(*a);
191 B *b3 = template_pointer_cast<B>(a);
192 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
193 // CHECK-FIXES: auto *b3 = template_pointer_cast<B>(a);
194 B &b4 = template_reference_cast<B>(*a);
195 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
196 // CHECK-FIXES: auto &b4 = template_reference_cast<B>(*a);
197 const B *b5 = template_const_pointer_cast<B>(a);
198 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
199 // CHECK-FIXES: const auto *b5 = template_const_pointer_cast<B>(a);
200 const B &b6 = template_const_reference_cast<B>(*a);
201 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
202 // CHECK-FIXES: const auto &b6 = template_const_reference_cast<B>(*a);
203 B *b7 = template_value_get<B *>("foo");
204 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
205 // CHECK-FIXES: auto *b7 = template_value_get<B *>("foo");
206 B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
207 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
208 // CHECK-FIXES: auto *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
209
210 S s;
211 const B *b10 = s.template_member_get<B>();
212 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
213 // CHECK-FIXES: const auto *b10 = s.template_member_get<B>();
214
215 // Don't warn when auto is already being used.
216 auto i2 = template_value_cast<int>(d);
217 auto *i3 = template_value_cast<int *>(d);
218 auto **i4 = template_value_cast<int **>(d);
219 auto &i5 = template_reference_cast<int>(d);
220
221 // Don't warn for implicit template arguments.
222 int i6 = max(i1, i2);
223
224 // Don't warn for mismatched var and initializer types.
225 A *a1 = template_value_cast<B *>(a);
226
227 // Don't warn for mismatched var types.
228 B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
229
230 // Don't warn for implicit variables.
231 for (auto &c : template_reference_cast<StringRef>(*a)) {
232 }
233 }
234