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