xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp (revision 2f02b5af6ecb973d3a7faad9b0daff22646e724d)
1bc8cff1dSNicolas van Kempen // RUN: %check_clang_tidy -std=c++20 %s modernize-use-starts-ends-with %t -- \
2bc8cff1dSNicolas van Kempen // RUN:   -- -isystem %clang_tidy_headers
3bc8cff1dSNicolas van Kempen 
4ef590698SNicolas van Kempen #include <string.h>
5bc8cff1dSNicolas van Kempen #include <string>
6bc8cff1dSNicolas van Kempen 
7bc8cff1dSNicolas van Kempen std::string foo(std::string);
8bc8cff1dSNicolas van Kempen std::string bar();
9bc8cff1dSNicolas van Kempen 
10bc8cff1dSNicolas van Kempen class sub_string : public std::string {};
11bc8cff1dSNicolas van Kempen class sub_sub_string : public sub_string {};
12bc8cff1dSNicolas van Kempen 
13bc8cff1dSNicolas van Kempen struct string_like {
14bc8cff1dSNicolas van Kempen   bool starts_with(const char *s) const;
15bc8cff1dSNicolas van Kempen   size_t find(const char *s, size_t pos = 0) const;
16bc8cff1dSNicolas van Kempen };
17bc8cff1dSNicolas van Kempen 
18bc8cff1dSNicolas van Kempen struct string_like_camel {
19bc8cff1dSNicolas van Kempen   bool startsWith(const char *s) const;
20bc8cff1dSNicolas van Kempen   size_t find(const char *s, size_t pos = 0) const;
21bc8cff1dSNicolas van Kempen };
22bc8cff1dSNicolas van Kempen 
23bc8cff1dSNicolas van Kempen struct prefer_underscore_version {
24bc8cff1dSNicolas van Kempen   bool starts_with(const char *s) const;
25bc8cff1dSNicolas van Kempen   bool startsWith(const char *s) const;
26bc8cff1dSNicolas van Kempen   size_t find(const char *s, size_t pos = 0) const;
27bc8cff1dSNicolas van Kempen };
28bc8cff1dSNicolas van Kempen 
29bc8cff1dSNicolas van Kempen struct prefer_underscore_version_flip {
30bc8cff1dSNicolas van Kempen   bool startsWith(const char *s) const;
31bc8cff1dSNicolas van Kempen   bool starts_with(const char *s) const;
32bc8cff1dSNicolas van Kempen   size_t find(const char *s, size_t pos = 0) const;
33bc8cff1dSNicolas van Kempen };
34bc8cff1dSNicolas van Kempen 
35bc8cff1dSNicolas van Kempen void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
36bc8cff1dSNicolas van Kempen           string_like sl, string_like_camel slc, prefer_underscore_version puv,
3718b50189SJulian Schmidt           prefer_underscore_version_flip puvf) {
38bc8cff1dSNicolas van Kempen   s.find("a") == 0;
3950844828SHelmut Januschka   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of find [modernize-use-starts-ends-with]
40bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
41bc8cff1dSNicolas van Kempen 
42bc8cff1dSNicolas van Kempen   (((((s)).find("a")))) == ((0));
43bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
44bc8cff1dSNicolas van Kempen   // CHECK-FIXES: ((s)).starts_with("a");
45bc8cff1dSNicolas van Kempen 
46bc8cff1dSNicolas van Kempen   (s + "a").find("a") == ((0));
47bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
48bc8cff1dSNicolas van Kempen   // CHECK-FIXES: (s + "a").starts_with("a");
49bc8cff1dSNicolas van Kempen 
50bc8cff1dSNicolas van Kempen   s.find(s) == 0;
51bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
52bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
53bc8cff1dSNicolas van Kempen 
54bc8cff1dSNicolas van Kempen   s.find("aaa") != 0;
55bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
56bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with("aaa");
57bc8cff1dSNicolas van Kempen 
58bc8cff1dSNicolas van Kempen   s.find(foo(foo(bar()))) != 0;
59bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
60bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with(foo(foo(bar())));
61bc8cff1dSNicolas van Kempen 
62bc8cff1dSNicolas van Kempen   if (s.find("....") == 0) { /* do something */ }
63bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
64bc8cff1dSNicolas van Kempen   // CHECK-FIXES: if (s.starts_with("...."))
65bc8cff1dSNicolas van Kempen 
66bc8cff1dSNicolas van Kempen   0 != s.find("a");
67bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
68bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with("a");
69bc8cff1dSNicolas van Kempen 
70bc8cff1dSNicolas van Kempen   s.rfind("a", 0) == 0;
7150844828SHelmut Januschka   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of rfind [modernize-use-starts-ends-with]
72bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
73bc8cff1dSNicolas van Kempen 
74bc8cff1dSNicolas van Kempen   s.rfind(s, 0) == 0;
75bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
76bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
77bc8cff1dSNicolas van Kempen 
78bc8cff1dSNicolas van Kempen   s.rfind("aaa", 0) != 0;
79bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
80bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with("aaa");
81bc8cff1dSNicolas van Kempen 
82bc8cff1dSNicolas van Kempen   s.rfind(foo(foo(bar())), 0) != 0;
83bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
84bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with(foo(foo(bar())));
85bc8cff1dSNicolas van Kempen 
86bc8cff1dSNicolas van Kempen   if (s.rfind("....", 0) == 0) { /* do something */ }
87bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
88bc8cff1dSNicolas van Kempen   // CHECK-FIXES: if (s.starts_with("...."))
89bc8cff1dSNicolas van Kempen 
90bc8cff1dSNicolas van Kempen   0 != s.rfind("a", 0);
91bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
92bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !s.starts_with("a");
93bc8cff1dSNicolas van Kempen 
94bc8cff1dSNicolas van Kempen   #define FIND find
95bc8cff1dSNicolas van Kempen   s.FIND("a") == 0;
96bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
97bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with("a")
98bc8cff1dSNicolas van Kempen 
99bc8cff1dSNicolas van Kempen   #define PREFIX "a"
100bc8cff1dSNicolas van Kempen   s.find(PREFIX) == 0;
101bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
102bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with(PREFIX)
103bc8cff1dSNicolas van Kempen 
104bc8cff1dSNicolas van Kempen   #define ZERO 0
105bc8cff1dSNicolas van Kempen   s.find("a") == ZERO;
106bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
107bc8cff1dSNicolas van Kempen   // CHECK-FIXES: s.starts_with("a")
108bc8cff1dSNicolas van Kempen 
109bc8cff1dSNicolas van Kempen   sv.find("a") == 0;
110bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
111bc8cff1dSNicolas van Kempen   // CHECK-FIXES: sv.starts_with("a");
112bc8cff1dSNicolas van Kempen 
113bc8cff1dSNicolas van Kempen   sv.rfind("a", 0) != 0;
114bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
115bc8cff1dSNicolas van Kempen   // CHECK-FIXES: !sv.starts_with("a");
116bc8cff1dSNicolas van Kempen 
117bc8cff1dSNicolas van Kempen   ss.find("a") == 0;
118bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
119bc8cff1dSNicolas van Kempen   // CHECK-FIXES: ss.starts_with("a");
120bc8cff1dSNicolas van Kempen 
121bc8cff1dSNicolas van Kempen   sss.find("a") == 0;
122bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
123bc8cff1dSNicolas van Kempen   // CHECK-FIXES: ss.starts_with("a");
124bc8cff1dSNicolas van Kempen 
125bc8cff1dSNicolas van Kempen   sl.find("a") == 0;
126bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
127bc8cff1dSNicolas van Kempen   // CHECK-FIXES: sl.starts_with("a");
128bc8cff1dSNicolas van Kempen 
129bc8cff1dSNicolas van Kempen   slc.find("a") == 0;
130bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use startsWith
131bc8cff1dSNicolas van Kempen   // CHECK-FIXES: slc.startsWith("a");
132bc8cff1dSNicolas van Kempen 
133bc8cff1dSNicolas van Kempen   puv.find("a") == 0;
134bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
135bc8cff1dSNicolas van Kempen   // CHECK-FIXES: puv.starts_with("a");
136bc8cff1dSNicolas van Kempen 
137bc8cff1dSNicolas van Kempen   puvf.find("a") == 0;
138bc8cff1dSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
139bc8cff1dSNicolas van Kempen   // CHECK-FIXES: puvf.starts_with("a");
140bc8cff1dSNicolas van Kempen 
141ef590698SNicolas van Kempen   s.compare(0, 1, "a") == 0;
14250844828SHelmut Januschka   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]
143ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
144ef590698SNicolas van Kempen 
145ef590698SNicolas van Kempen   s.compare(0, 1, "a") != 0;
14650844828SHelmut Januschka   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]
147ef590698SNicolas van Kempen   // CHECK-FIXES: !s.starts_with("a");
148ef590698SNicolas van Kempen 
149ef590698SNicolas van Kempen   s.compare(0, strlen("a"), "a") == 0;
150ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
151ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
152ef590698SNicolas van Kempen 
153ef590698SNicolas van Kempen   s.compare(0, std::strlen("a"), "a") == 0;
154ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
155ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
156ef590698SNicolas van Kempen 
157ef590698SNicolas van Kempen   s.compare(0, std::strlen(("a")), "a") == 0;
158ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
159ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
160ef590698SNicolas van Kempen 
161ef590698SNicolas van Kempen   s.compare(0, std::strlen(("a")), (("a"))) == 0;
162ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
163ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with("a");
164ef590698SNicolas van Kempen 
165ef590698SNicolas van Kempen   s.compare(0, s.size(), s) == 0;
166ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
167ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
168ef590698SNicolas van Kempen 
169ef590698SNicolas van Kempen   s.compare(0, s.length(), s) == 0;
170ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
171ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
172ef590698SNicolas van Kempen 
173ef590698SNicolas van Kempen   0 != s.compare(0, sv.length(), sv);
174ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
175ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with(sv);
176ef590698SNicolas van Kempen 
177ef590698SNicolas van Kempen   #define LENGTH(x) (x).length()
178ef590698SNicolas van Kempen   s.compare(0, LENGTH(s), s) == 0;
179ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
180ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
181ef590698SNicolas van Kempen 
182ef590698SNicolas van Kempen   s.compare(ZERO, LENGTH(s), s) == ZERO;
183ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
184ef590698SNicolas van Kempen   // CHECK-FIXES: s.starts_with(s);
185ef590698SNicolas van Kempen 
186ef590698SNicolas van Kempen   s.compare(ZERO, LENGTH(sv), sv) != 0;
187ef590698SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
188ef590698SNicolas van Kempen   // CHECK-FIXES: !s.starts_with(sv);
189ef590698SNicolas van Kempen 
190f1367a47SNicolas van Kempen   s.compare(s.size() - 6, 6, "suffix") == 0;
191f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
192f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with("suffix");
193f1367a47SNicolas van Kempen 
194f1367a47SNicolas van Kempen   s.compare(s.size() - 6, strlen("abcdef"), "suffix") == 0;
195f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
196f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with("suffix");
197f1367a47SNicolas van Kempen 
198f1367a47SNicolas van Kempen   std::string suffix = "suffix";
199f1367a47SNicolas van Kempen   s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0;
200f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
201f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
202f1367a47SNicolas van Kempen 
203f1367a47SNicolas van Kempen   s.rfind("suffix") == s.size() - 6;
204f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
205f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with("suffix");
206f1367a47SNicolas van Kempen 
207f1367a47SNicolas van Kempen   s.rfind("suffix") == s.size() - strlen("suffix");
208f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
209f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with("suffix");
210f1367a47SNicolas van Kempen 
211f1367a47SNicolas van Kempen   s.rfind(suffix) == s.size() - suffix.size();
212f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
213f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
214f1367a47SNicolas van Kempen 
215f1367a47SNicolas van Kempen   s.rfind(suffix, std::string::npos) == s.size() - suffix.size();
216f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
217f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
218f1367a47SNicolas van Kempen 
219f1367a47SNicolas van Kempen   s.rfind(suffix) == (s.size() - suffix.size());
220f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
221f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
222f1367a47SNicolas van Kempen 
223f1367a47SNicolas van Kempen   s.rfind(suffix, s.npos) == (s.size() - suffix.size());
224f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
225f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
226f1367a47SNicolas van Kempen 
227f1367a47SNicolas van Kempen   s.rfind(suffix, s.npos) == (((s.size()) - (suffix.size())));
228f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
229f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
230f1367a47SNicolas van Kempen 
231f1367a47SNicolas van Kempen   s.rfind(suffix) != s.size() - suffix.size();
232f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
233f1367a47SNicolas van Kempen   // CHECK-FIXES: !s.ends_with(suffix);
234f1367a47SNicolas van Kempen 
235f1367a47SNicolas van Kempen   (s.size() - suffix.size()) == s.rfind(suffix);
236f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
237f1367a47SNicolas van Kempen   // CHECK-FIXES: s.ends_with(suffix);
238f1367a47SNicolas van Kempen 
239f1367a47SNicolas van Kempen   struct S {
240f1367a47SNicolas van Kempen     std::string s;
241f1367a47SNicolas van Kempen   } t;
242f1367a47SNicolas van Kempen   t.s.rfind(suffix) == (t.s.size() - suffix.size());
243f1367a47SNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use ends_with
244f1367a47SNicolas van Kempen   // CHECK-FIXES: t.s.ends_with(suffix);
245f1367a47SNicolas van Kempen 
246bc8cff1dSNicolas van Kempen   // Expressions that don't trigger the check are here.
247bc8cff1dSNicolas van Kempen   #define EQ(x, y) ((x) == (y))
248bc8cff1dSNicolas van Kempen   EQ(s.find("a"), 0);
249bc8cff1dSNicolas van Kempen 
250bc8cff1dSNicolas van Kempen   #define DOTFIND(x, y) (x).find(y)
251bc8cff1dSNicolas van Kempen   DOTFIND(s, "a") == 0;
252ef590698SNicolas van Kempen 
253ef590698SNicolas van Kempen   #define STARTS_WITH_COMPARE(x, y) (x).compare(0, (x).size(), (y))
254ef590698SNicolas van Kempen   STARTS_WITH_COMPARE(s, s) == 0;
255ef590698SNicolas van Kempen 
256ef590698SNicolas van Kempen   s.compare(0, 1, "ab") == 0;
257f1367a47SNicolas van Kempen   s.rfind(suffix, 1) == s.size() - suffix.size();
25850844828SHelmut Januschka 
25950844828SHelmut Januschka   #define STR(x) std::string(x)
26050844828SHelmut Januschka   0 == STR(s).find("a");
26150844828SHelmut Januschka 
26250844828SHelmut Januschka   #define STRING s
26350844828SHelmut Januschka   if (0 == STRING.find("ala")) { /* do something */}
26450844828SHelmut Januschka }
26550844828SHelmut Januschka 
26650844828SHelmut Januschka void test_substr() {
26750844828SHelmut Januschka     std::string str("hello world");
26850844828SHelmut Januschka     std::string prefix = "hello";
26950844828SHelmut Januschka 
27050844828SHelmut Januschka     // Basic pattern
27150844828SHelmut Januschka     str.substr(0, 5) == "hello";
27250844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
27350844828SHelmut Januschka     // CHECK-FIXES: str.starts_with("hello");
27450844828SHelmut Januschka 
27550844828SHelmut Januschka     // With string literal on left side
27650844828SHelmut Januschka     "hello" == str.substr(0, 5);
27750844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
27850844828SHelmut Januschka     // CHECK-FIXES: str.starts_with("hello");
27950844828SHelmut Januschka 
28050844828SHelmut Januschka     // Inequality comparison
28150844828SHelmut Januschka     str.substr(0, 5) != "world";
28250844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
28350844828SHelmut Januschka     // CHECK-FIXES: !str.starts_with("world");
28450844828SHelmut Januschka 
28550844828SHelmut Januschka     // Ensure non-zero start position is not transformed
28650844828SHelmut Januschka     str.substr(1, 5) == "hello";
28750844828SHelmut Januschka     str.substr(0, 4) == "hello"; // Length mismatch
28850844828SHelmut Januschka 
28950844828SHelmut Januschka     size_t len = 5;
29050844828SHelmut Januschka     str.substr(0, len) == "hello"; // Non-constant length
29150844828SHelmut Januschka 
29250844828SHelmut Januschka     // String literal with size calculation
29350844828SHelmut Januschka     str.substr(0, strlen("hello")) == "hello";
29450844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
29550844828SHelmut Januschka     // CHECK-FIXES: str.starts_with("hello");
29650844828SHelmut Januschka 
29750844828SHelmut Januschka     str.substr(0, prefix.size()) == prefix;
29850844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
29950844828SHelmut Januschka     // CHECK-FIXES: str.starts_with(prefix);
30050844828SHelmut Januschka 
30150844828SHelmut Januschka     str.substr(0, prefix.length()) == prefix;
30250844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
30350844828SHelmut Januschka     // CHECK-FIXES: str.starts_with(prefix);
30450844828SHelmut Januschka 
30550844828SHelmut Januschka     // Tests to verify macro behavior
30650844828SHelmut Januschka     #define MSG "hello"
30750844828SHelmut Januschka     str.substr(0, strlen(MSG)) == MSG;
30850844828SHelmut Januschka     // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
30950844828SHelmut Januschka     // CHECK-FIXES: str.starts_with(MSG);
31050844828SHelmut Januschka 
31150844828SHelmut Januschka     #define STARTS_WITH(X, Y) (X).substr(0, (Y).size()) == (Y)
31250844828SHelmut Januschka     STARTS_WITH(str, prefix);
31350844828SHelmut Januschka 
31450844828SHelmut Januschka     #define SUBSTR(X, A, B) (X).substr((A), (B))
31550844828SHelmut Januschka     SUBSTR(str, 0, 6) == "prefix";
31650844828SHelmut Januschka 
31750844828SHelmut Januschka     #define STR() str
31850844828SHelmut Januschka     SUBSTR(STR(), 0, 6) == "prefix";
31950844828SHelmut Januschka     "prefix" == SUBSTR(STR(), 0, 6);
32050844828SHelmut Januschka 
32150844828SHelmut Januschka     str.substr(0, strlen("hello123")) == "hello";
322bc8cff1dSNicolas van Kempen }
323*2f02b5afSNicolas van Kempen 
324*2f02b5afSNicolas van Kempen void test_operator_rewriting(std::string str, std::string prefix) {
325*2f02b5afSNicolas van Kempen   str.substr(0, prefix.size()) == prefix;
326*2f02b5afSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr
327*2f02b5afSNicolas van Kempen   // CHECK-FIXES: str.starts_with(prefix);
328*2f02b5afSNicolas van Kempen 
329*2f02b5afSNicolas van Kempen   str.substr(0, prefix.size()) != prefix;
330*2f02b5afSNicolas van Kempen   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr
331*2f02b5afSNicolas van Kempen   // CHECK-FIXES: !str.starts_with(prefix);
332*2f02b5afSNicolas van Kempen }
333