1 // RUN: %check_clang_tidy -std=c++11-or-later %s abseil-faster-strsplit-delimiter %t
2 
3 namespace absl {
4 
5 class string_view {
6   public:
7     string_view();
8     string_view(const char *);
9 };
10 
11 namespace strings_internal {
12 struct Splitter {};
13 struct MaxSplitsImpl {
14   MaxSplitsImpl();
15   ~MaxSplitsImpl();
16 };
17 } //namespace strings_internal
18 
19 template <typename Delim>
StrSplit(absl::string_view,Delim)20 strings_internal::Splitter StrSplit(absl::string_view, Delim) {
21   return {};
22 }
23 template <typename Delim, typename Pred>
StrSplit(absl::string_view,Delim,Pred)24 strings_internal::Splitter StrSplit(absl::string_view, Delim, Pred) {
25   return {};
26 }
27 
28 class ByAnyChar {
29   public:
30     explicit ByAnyChar(absl::string_view);
31     ~ByAnyChar();
32 };
33 
34 template <typename Delim>
MaxSplits(Delim,int)35 strings_internal::MaxSplitsImpl MaxSplits(Delim, int) {
36   return {};
37 }
38 
39 } //namespace absl
40 
SplitDelimiters()41 void SplitDelimiters() {
42   absl::StrSplit("ABC", "A");
43   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
44   // CHECK-FIXES: absl::StrSplit("ABC", 'A');
45 
46   absl::StrSplit("ABC", "\x01");
47   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
48   // CHECK-FIXES: absl::StrSplit("ABC", '\x01');
49 
50   absl::StrSplit("ABC", "\001");
51   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
52   // CHECK-FIXES: absl::StrSplit("ABC", '\001');
53 
54   absl::StrSplit("ABC", R"(A)");
55   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
56   // CHECK-FIXES: absl::StrSplit("ABC", 'A');
57 
58   absl::StrSplit("ABC", R"(')");
59   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
60   // CHECK-FIXES: absl::StrSplit("ABC", '\'');
61 
62   absl::StrSplit("ABC", R"(
63 )");
64   // CHECK-MESSAGES: [[@LINE-2]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
65   // CHECK-FIXES: absl::StrSplit("ABC", '\n');
66 
67   absl::StrSplit("ABC", R"delimiter(A)delimiter");
68   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit() called with a string literal consisting of a single character; consider using the character overload [abseil-faster-strsplit-delimiter]
69   // CHECK-FIXES: absl::StrSplit("ABC", 'A');
70 
71   absl::StrSplit("ABC", absl::ByAnyChar("\n"));
72   // CHECK-MESSAGES: [[@LINE-1]]:41: warning: absl::StrSplit()
73   // CHECK-FIXES: absl::StrSplit("ABC", '\n');
74 
75   // Works with predicate
76   absl::StrSplit("ABC", "A", [](absl::string_view) { return true; });
77   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
78   // CHECK-FIXES: absl::StrSplit("ABC", 'A', [](absl::string_view) { return true; });
79 
80   // Doesn't do anything with other strings lenghts.
81   absl::StrSplit("ABC", "AB");
82   absl::StrSplit("ABC", absl::ByAnyChar(""));
83   absl::StrSplit("ABC", absl::ByAnyChar(" \t"));
84 
85   // Escapes a single quote in the resulting character literal.
86   absl::StrSplit("ABC", "'");
87   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
88   // CHECK-FIXES: absl::StrSplit("ABC", '\'');
89 
90   absl::StrSplit("ABC", "\"");
91   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
92   // CHECK-FIXES: absl::StrSplit("ABC", '\"');
93 
94   absl::StrSplit("ABC", absl::MaxSplits("\t", 1));
95   // CHECK-MESSAGES: [[@LINE-1]]:41: warning: absl::MaxSplits()
96   // CHECK-FIXES: absl::StrSplit("ABC", absl::MaxSplits('\t', 1));
97 
98   auto delim = absl::MaxSplits(absl::ByAnyChar(" "), 1);
99   // CHECK-MESSAGES: [[@LINE-1]]:48: warning: absl::MaxSplits()
100   // CHECK-FIXES: auto delim = absl::MaxSplits(' ', 1);
101 }
102 
103 #define MACRO(str) absl::StrSplit("ABC", str)
104 
Macro()105 void Macro() {
106   MACRO("A");
107 }
108 
109 template <typename T>
FunctionTemplate()110 void FunctionTemplate() {
111   // This one should not warn because ByAnyChar is a dependent type.
112   absl::StrSplit("TTT", T("A"));
113 
114   // This one will warn, but we are checking that we get a correct warning only
115   // once.
116   absl::StrSplit("TTT", "A");
117   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: absl::StrSplit()
118   // CHECK-FIXES: absl::StrSplit("TTT", 'A');
119 }
120 
FunctionTemplateCaller()121 void FunctionTemplateCaller() {
122   FunctionTemplate<absl::ByAnyChar>();
123   FunctionTemplate<absl::string_view>();
124 }
125