xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/boost/use-to-string.cpp (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s boost-use-to-string %t
2*89a1d03eSRichard 
3*89a1d03eSRichard namespace std {
4*89a1d03eSRichard 
5*89a1d03eSRichard template <typename T>
6*89a1d03eSRichard class basic_string {};
7*89a1d03eSRichard 
8*89a1d03eSRichard using string = basic_string<char>;
9*89a1d03eSRichard using wstring = basic_string<wchar_t>;
10*89a1d03eSRichard }
11*89a1d03eSRichard 
12*89a1d03eSRichard namespace boost {
13*89a1d03eSRichard template <typename T, typename V>
lexical_cast(const V &)14*89a1d03eSRichard T lexical_cast(const V &) {
15*89a1d03eSRichard   return T();
16*89a1d03eSRichard };
17*89a1d03eSRichard }
18*89a1d03eSRichard 
19*89a1d03eSRichard struct my_weird_type {};
20*89a1d03eSRichard 
fun(const std::string &)21*89a1d03eSRichard std::string fun(const std::string &) {}
22*89a1d03eSRichard 
test_to_string1()23*89a1d03eSRichard void test_to_string1() {
24*89a1d03eSRichard 
25*89a1d03eSRichard   auto xa = boost::lexical_cast<std::string>(5);
26*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string instead of boost::lexical_cast<std::string> [boost-use-to-string]
27*89a1d03eSRichard   // CHECK-FIXES: auto xa = std::to_string(5);
28*89a1d03eSRichard 
29*89a1d03eSRichard   auto z = boost::lexical_cast<std::string>(42LL);
30*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::to_string
31*89a1d03eSRichard   // CHECK-FIXES: auto z = std::to_string(42LL);
32*89a1d03eSRichard 
33*89a1d03eSRichard   // this should not trigger
34*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(42.0));
35*89a1d03eSRichard   auto non = boost::lexical_cast<my_weird_type>(42);
36*89a1d03eSRichard   boost::lexical_cast<int>("12");
37*89a1d03eSRichard }
38*89a1d03eSRichard 
test_to_string2()39*89a1d03eSRichard void test_to_string2() {
40*89a1d03eSRichard   int a;
41*89a1d03eSRichard   long b;
42*89a1d03eSRichard   long long c;
43*89a1d03eSRichard   unsigned d;
44*89a1d03eSRichard   unsigned long e;
45*89a1d03eSRichard   unsigned long long f;
46*89a1d03eSRichard   float g;
47*89a1d03eSRichard   double h;
48*89a1d03eSRichard   long double i;
49*89a1d03eSRichard   bool j;
50*89a1d03eSRichard 
51*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(a));
52*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
53*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(a));
54*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(b));
55*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
56*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(b));
57*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(c));
58*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
59*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(c));
60*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(d));
61*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
62*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(d));
63*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(e));
64*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
65*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(e));
66*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(f));
67*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string
68*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_string(f));
69*89a1d03eSRichard 
70*89a1d03eSRichard   // No change for floating numbers.
71*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(g));
72*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(h));
73*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(i));
74*89a1d03eSRichard   // And bool.
75*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(j));
76*89a1d03eSRichard }
77*89a1d03eSRichard 
fun(const std::wstring &)78*89a1d03eSRichard std::string fun(const std::wstring &) {}
79*89a1d03eSRichard 
test_to_wstring()80*89a1d03eSRichard void test_to_wstring() {
81*89a1d03eSRichard   int a;
82*89a1d03eSRichard   long b;
83*89a1d03eSRichard   long long c;
84*89a1d03eSRichard   unsigned d;
85*89a1d03eSRichard   unsigned long e;
86*89a1d03eSRichard   unsigned long long f;
87*89a1d03eSRichard   float g;
88*89a1d03eSRichard   double h;
89*89a1d03eSRichard   long double i;
90*89a1d03eSRichard   bool j;
91*89a1d03eSRichard 
92*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(a));
93*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring instead of boost::lexical_cast<std::wstring> [boost-use-to-string]
94*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(a));
95*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(b));
96*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
97*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(b));
98*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(c));
99*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
100*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(c));
101*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(d));
102*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
103*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(d));
104*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(e));
105*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
106*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(e));
107*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(f));
108*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring
109*89a1d03eSRichard   // CHECK-FIXES: fun(std::to_wstring(f));
110*89a1d03eSRichard 
111*89a1d03eSRichard   // No change for floating numbers
112*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(g));
113*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(h));
114*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(i));
115*89a1d03eSRichard   // and bool.
116*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>(j));
117*89a1d03eSRichard }
118*89a1d03eSRichard 
119*89a1d03eSRichard const auto glob = boost::lexical_cast<std::string>(42);
120*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use std::to_string
121*89a1d03eSRichard // CHECK-FIXES: const auto glob = std::to_string(42);
122*89a1d03eSRichard 
123*89a1d03eSRichard template <typename T>
string_as_T(T t=T ())124*89a1d03eSRichard void string_as_T(T t = T()) {
125*89a1d03eSRichard   boost::lexical_cast<std::string>(42);
126*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string
127*89a1d03eSRichard   // CHECK-FIXES: std::to_string(42);
128*89a1d03eSRichard 
129*89a1d03eSRichard   boost::lexical_cast<T>(42);
130*89a1d03eSRichard   string_as_T(boost::lexical_cast<T>(42));
131*89a1d03eSRichard   auto p = boost::lexical_cast<T>(42);
132*89a1d03eSRichard   auto p2 = (T)boost::lexical_cast<T>(42);
133*89a1d03eSRichard   auto p3 = static_cast<T>(boost::lexical_cast<T>(42));
134*89a1d03eSRichard }
135*89a1d03eSRichard 
136*89a1d03eSRichard #define my_to_string boost::lexical_cast<std::string>
137*89a1d03eSRichard 
no_fixup_inside_macro()138*89a1d03eSRichard void no_fixup_inside_macro() {
139*89a1d03eSRichard   my_to_string(12);
140*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string
141*89a1d03eSRichard }
142*89a1d03eSRichard 
no_warnings()143*89a1d03eSRichard void no_warnings() {
144*89a1d03eSRichard   fun(boost::lexical_cast<std::string>("abc"));
145*89a1d03eSRichard   fun(boost::lexical_cast<std::wstring>("abc"));
146*89a1d03eSRichard   fun(boost::lexical_cast<std::string>(my_weird_type{}));
147*89a1d03eSRichard   string_as_T<int>();
148*89a1d03eSRichard   string_as_T<std::string>();
149*89a1d03eSRichard }
150*89a1d03eSRichard 
151*89a1d03eSRichard struct Fields {
152*89a1d03eSRichard   int integer;
153*89a1d03eSRichard   float floating;
154*89a1d03eSRichard   Fields* wierd;
getConstIntegerFields155*89a1d03eSRichard   const int &getConstInteger() const {return integer;}
156*89a1d03eSRichard };
157*89a1d03eSRichard 
testFields()158*89a1d03eSRichard void testFields() {
159*89a1d03eSRichard   Fields fields;
160*89a1d03eSRichard   auto s1 = boost::lexical_cast<std::string>(fields.integer);
161*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string
162*89a1d03eSRichard   // CHECK-FIXES: auto s1 = std::to_string(fields.integer);
163*89a1d03eSRichard 
164*89a1d03eSRichard   auto s2 = boost::lexical_cast<std::string>(fields.floating);
165*89a1d03eSRichard   auto s3 = boost::lexical_cast<std::string>(fields.wierd);
166*89a1d03eSRichard   auto s4 = boost::lexical_cast<std::string>(fields.getConstInteger());
167*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string
168*89a1d03eSRichard   // CHECK-FIXES: auto s4 = std::to_string(fields.getConstInteger());
169*89a1d03eSRichard }
170