xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp (revision e8a3ddafe063c970df9c23e803812369abde4c82)
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