189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-use-auto %t -- \
2*e8a3ddafSNathan James // RUN: -config="{CheckOptions: {modernize-use-auto.MinTypeNameLength: '0'}}" \
389a1d03eSRichard // RUN: -- -I %S/Inputs/use-auto -frtti
489a1d03eSRichard
589a1d03eSRichard struct A {
~AA689a1d03eSRichard virtual ~A() {}
789a1d03eSRichard };
889a1d03eSRichard
989a1d03eSRichard struct B : public A {};
1089a1d03eSRichard
1189a1d03eSRichard struct C {};
1289a1d03eSRichard
f_static_cast()1389a1d03eSRichard void f_static_cast() {
1489a1d03eSRichard long l = 1;
1589a1d03eSRichard int i1 = static_cast<int>(l);
1689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
1789a1d03eSRichard // CHECK-FIXES: auto i1 = static_cast<int>(l);
1889a1d03eSRichard
1989a1d03eSRichard const int i2 = static_cast<int>(l);
2089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
2189a1d03eSRichard // CHECK-FIXES: const auto i2 = static_cast<int>(l);
2289a1d03eSRichard
2389a1d03eSRichard long long ll = static_cast<long long>(l);
2489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
2589a1d03eSRichard // CHECK-FIXES: auto ll = static_cast<long long>(l);
2689a1d03eSRichard unsigned long long ull = static_cast<unsigned long long>(l);
2789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
2889a1d03eSRichard // CHECK-FIXES: auto ull = static_cast<unsigned long long>(l);
2989a1d03eSRichard unsigned int ui = static_cast<unsigned int>(l);
3089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
3189a1d03eSRichard // CHECK-FIXES: auto ui = static_cast<unsigned int>(l);
3289a1d03eSRichard long double ld = static_cast<long double>(l);
3389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
3489a1d03eSRichard // CHECK-FIXES: auto ld = static_cast<long double>(l);
3589a1d03eSRichard
3689a1d03eSRichard A *a = new B();
3789a1d03eSRichard B *b1 = static_cast<B *>(a);
3889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
3989a1d03eSRichard // CHECK-FIXES: auto *b1 = static_cast<B *>(a);
4089a1d03eSRichard
4189a1d03eSRichard B *const b2 = static_cast<B *>(a);
4289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
4389a1d03eSRichard // CHECK-FIXES: auto *const b2 = static_cast<B *>(a);
4489a1d03eSRichard
4589a1d03eSRichard const B *b3 = static_cast<const B *>(a);
4689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
4789a1d03eSRichard // CHECK-FIXES: const auto *b3 = static_cast<const B *>(a);
4889a1d03eSRichard
4989a1d03eSRichard B &b4 = static_cast<B &>(*a);
5089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
5189a1d03eSRichard // CHECK-FIXES: auto &b4 = static_cast<B &>(*a);
5289a1d03eSRichard
5389a1d03eSRichard const B &b5 = static_cast<const B &>(*a);
5489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
5589a1d03eSRichard // CHECK-FIXES: const auto &b5 = static_cast<const B &>(*a);
5689a1d03eSRichard
5789a1d03eSRichard B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
5889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
5989a1d03eSRichard // CHECK-FIXES: auto &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
6089a1d03eSRichard
6189a1d03eSRichard // Don't warn when non-cast involved
6289a1d03eSRichard long double cast = static_cast<long double>(l), noncast = 5;
6389a1d03eSRichard
6489a1d03eSRichard // Don't warn when auto is already being used.
6589a1d03eSRichard auto i3 = static_cast<int>(l);
6689a1d03eSRichard auto *b8 = static_cast<B *>(a);
6789a1d03eSRichard auto &b9 = static_cast<B &>(*a);
6889a1d03eSRichard }
6989a1d03eSRichard
f_dynamic_cast()7089a1d03eSRichard void f_dynamic_cast() {
7189a1d03eSRichard A *a = new B();
7289a1d03eSRichard B *b1 = dynamic_cast<B *>(a);
7389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
7489a1d03eSRichard // CHECK-FIXES: auto *b1 = dynamic_cast<B *>(a);
7589a1d03eSRichard
7689a1d03eSRichard B &b2 = dynamic_cast<B &>(*a);
7789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
7889a1d03eSRichard // CHECK-FIXES: auto &b2 = dynamic_cast<B &>(*a);
7989a1d03eSRichard }
8089a1d03eSRichard
f_reinterpret_cast()8189a1d03eSRichard void f_reinterpret_cast() {
8289a1d03eSRichard auto *a = new A();
8389a1d03eSRichard C *c1 = reinterpret_cast<C *>(a);
8489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
8589a1d03eSRichard // CHECK-FIXES: auto *c1 = reinterpret_cast<C *>(a);
8689a1d03eSRichard
8789a1d03eSRichard C &c2 = reinterpret_cast<C &>(*a);
8889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
8989a1d03eSRichard // CHECK-FIXES: auto &c2 = reinterpret_cast<C &>(*a);
9089a1d03eSRichard }
9189a1d03eSRichard
f_const_cast()9289a1d03eSRichard void f_const_cast() {
9389a1d03eSRichard const A *a1 = new A();
9489a1d03eSRichard A *a2 = const_cast<A *>(a1);
9589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
9689a1d03eSRichard // CHECK-FIXES: auto *a2 = const_cast<A *>(a1);
9789a1d03eSRichard A &a3 = const_cast<A &>(*a1);
9889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
9989a1d03eSRichard // CHECK-FIXES: auto &a3 = const_cast<A &>(*a1);
10089a1d03eSRichard }
10189a1d03eSRichard
10289a1d03eSRichard typedef unsigned char xmlChar;
10389a1d03eSRichard #define BAD_CAST (xmlChar *)
10489a1d03eSRichard
10589a1d03eSRichard #define XMLCHAR_CAST(x) (xmlChar *)(x)
10689a1d03eSRichard
10789a1d03eSRichard #define CAST_IN_MACRO(x) \
10889a1d03eSRichard do { \
10989a1d03eSRichard xmlChar *s = (xmlChar *)(x); \
11089a1d03eSRichard } while (false);
11189a1d03eSRichard // CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
11289a1d03eSRichard
f_cstyle_cast()11389a1d03eSRichard void f_cstyle_cast() {
11489a1d03eSRichard auto *a = new A();
11589a1d03eSRichard C *c1 = (C *)a;
11689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
11789a1d03eSRichard // CHECK-FIXES: auto *c1 = (C *)a;
11889a1d03eSRichard
11989a1d03eSRichard C &c2 = (C &)*a;
12089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
12189a1d03eSRichard // CHECK-FIXES: auto &c2 = (C &)*a;
12289a1d03eSRichard
12389a1d03eSRichard xmlChar *s = BAD_CAST "xml";
12489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
12589a1d03eSRichard // CHECK-FIXES: auto *s = BAD_CAST "xml";
12689a1d03eSRichard xmlChar *t = XMLCHAR_CAST("xml");
12789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
12889a1d03eSRichard // CHECK-FIXES: auto *t = XMLCHAR_CAST("xml");
12989a1d03eSRichard CAST_IN_MACRO("xml");
13089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
13189a1d03eSRichard }
13289a1d03eSRichard
f_functional_cast()13389a1d03eSRichard void f_functional_cast() {
13489a1d03eSRichard long l = 1;
13589a1d03eSRichard int i1 = int(l);
13689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
13789a1d03eSRichard // CHECK-FIXES: auto i1 = int(l);
13889a1d03eSRichard
13989a1d03eSRichard B b;
14089a1d03eSRichard A a = A(b);
14189a1d03eSRichard }
14289a1d03eSRichard
14389a1d03eSRichard class StringRef
14489a1d03eSRichard {
14589a1d03eSRichard public:
14689a1d03eSRichard StringRef(const char *);
14789a1d03eSRichard const char *begin() const;
14889a1d03eSRichard const char *end() const;
14989a1d03eSRichard };
15089a1d03eSRichard
15189a1d03eSRichard template <typename T, typename U>
15289a1d03eSRichard T template_value_cast(const U &u);
15389a1d03eSRichard
15489a1d03eSRichard template <typename T, typename U>
15589a1d03eSRichard T *template_pointer_cast(U *u);
15689a1d03eSRichard
15789a1d03eSRichard template <typename T, typename U>
15889a1d03eSRichard T &template_reference_cast(U &u);
15989a1d03eSRichard
16089a1d03eSRichard template <typename T, typename U>
16189a1d03eSRichard const T *template_const_pointer_cast(const U *u);
16289a1d03eSRichard
16389a1d03eSRichard template <typename T, typename U>
16489a1d03eSRichard const T &template_const_reference_cast(const U &u);
16589a1d03eSRichard
16689a1d03eSRichard template <typename T>
16789a1d03eSRichard T template_value_get(StringRef s);
16889a1d03eSRichard
16989a1d03eSRichard struct S {
17089a1d03eSRichard template <typename T>
17189a1d03eSRichard const T *template_member_get();
17289a1d03eSRichard };
17389a1d03eSRichard
17489a1d03eSRichard template <typename T>
17589a1d03eSRichard T max(T t1, T t2);
17689a1d03eSRichard
f_template_cast()17789a1d03eSRichard void f_template_cast()
17889a1d03eSRichard {
17989a1d03eSRichard double d = 0;
18089a1d03eSRichard int i1 = template_value_cast<int>(d);
18189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
18289a1d03eSRichard // CHECK-FIXES: auto i1 = template_value_cast<int>(d);
18389a1d03eSRichard
18489a1d03eSRichard A *a = new B();
18589a1d03eSRichard B *b1 = template_value_cast<B *>(a);
18689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
18789a1d03eSRichard // CHECK-FIXES: auto *b1 = template_value_cast<B *>(a);
18889a1d03eSRichard B &b2 = template_value_cast<B &>(*a);
18989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
19089a1d03eSRichard // CHECK-FIXES: auto &b2 = template_value_cast<B &>(*a);
19189a1d03eSRichard B *b3 = template_pointer_cast<B>(a);
19289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
19389a1d03eSRichard // CHECK-FIXES: auto *b3 = template_pointer_cast<B>(a);
19489a1d03eSRichard B &b4 = template_reference_cast<B>(*a);
19589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
19689a1d03eSRichard // CHECK-FIXES: auto &b4 = template_reference_cast<B>(*a);
19789a1d03eSRichard const B *b5 = template_const_pointer_cast<B>(a);
19889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
19989a1d03eSRichard // CHECK-FIXES: const auto *b5 = template_const_pointer_cast<B>(a);
20089a1d03eSRichard const B &b6 = template_const_reference_cast<B>(*a);
20189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
20289a1d03eSRichard // CHECK-FIXES: const auto &b6 = template_const_reference_cast<B>(*a);
20389a1d03eSRichard B *b7 = template_value_get<B *>("foo");
20489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
20589a1d03eSRichard // CHECK-FIXES: auto *b7 = template_value_get<B *>("foo");
20689a1d03eSRichard B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
20789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
20889a1d03eSRichard // CHECK-FIXES: auto *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
20989a1d03eSRichard
21089a1d03eSRichard S s;
21189a1d03eSRichard const B *b10 = s.template_member_get<B>();
21289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
21389a1d03eSRichard // CHECK-FIXES: const auto *b10 = s.template_member_get<B>();
21489a1d03eSRichard
21589a1d03eSRichard // Don't warn when auto is already being used.
21689a1d03eSRichard auto i2 = template_value_cast<int>(d);
21789a1d03eSRichard auto *i3 = template_value_cast<int *>(d);
21889a1d03eSRichard auto **i4 = template_value_cast<int **>(d);
21989a1d03eSRichard auto &i5 = template_reference_cast<int>(d);
22089a1d03eSRichard
22189a1d03eSRichard // Don't warn for implicit template arguments.
22289a1d03eSRichard int i6 = max(i1, i2);
22389a1d03eSRichard
22489a1d03eSRichard // Don't warn for mismatched var and initializer types.
22589a1d03eSRichard A *a1 = template_value_cast<B *>(a);
22689a1d03eSRichard
22789a1d03eSRichard // Don't warn for mismatched var types.
22889a1d03eSRichard B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
22989a1d03eSRichard
23089a1d03eSRichard // Don't warn for implicit variables.
23189a1d03eSRichard for (auto &c : template_reference_cast<StringRef>(*a)) {
23289a1d03eSRichard }
23389a1d03eSRichard }
234