performance-faster-string-find.cpp
4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// RUN: %check_clang_tidy %s performance-faster-string-find %t
// RUN: %check_clang_tidy -check-suffix=CUSTOM %s performance-faster-string-find %t -- \
// RUN: -config="{CheckOptions: \
// RUN: [{key: performance-faster-string-find.StringLikeClasses, \
// RUN: value: '::llvm::StringRef;'}]}"
namespace std {
template <typename Char>
struct basic_string {
int find(const Char *, int = 0) const;
int find(const Char *, int, int) const;
int rfind(const Char *) const;
int find_first_of(const Char *) const;
int find_first_not_of(const Char *) const;
int find_last_of(const Char *) const;
int find_last_not_of(const Char *) const;
};
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
template <typename Char>
struct basic_string_view {
int find(const Char *, int = 0) const;
int find(const Char *, int, int) const;
int rfind(const Char *) const;
int find_first_of(const Char *) const;
int find_first_not_of(const Char *) const;
int find_last_of(const Char *) const;
int find_last_not_of(const Char *) const;
};
typedef basic_string_view<char> string_view;
typedef basic_string_view<wchar_t> wstring_view;
} // namespace std
namespace llvm {
struct StringRef {
int find(const char *) const;
};
} // namespace llvm
struct NotStringRef {
int find(const char *);
};
void StringFind() {
std::string Str;
Str.find("a");
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal consisting of a single character; consider using the more effective overload accepting a character [performance-faster-string-find]
// CHECK-FIXES: Str.find('a');
// Works with the pos argument.
Str.find("a", 1);
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find('a', 1);
// Doens't work with strings smaller or larger than 1 char.
Str.find("");
Str.find("ab");
// Doesn't do anything with the 3 argument overload.
Str.find("a", 1, 1);
// Other methods that can also be replaced
Str.rfind("a");
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal
// CHECK-FIXES: Str.rfind('a');
Str.find_first_of("a");
// CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'find_first_of' called with a string
// CHECK-FIXES: Str.find_first_of('a');
Str.find_first_not_of("a");
// CHECK-MESSAGES: [[@LINE-1]]:25: warning: 'find_first_not_of' called with a
// CHECK-FIXES: Str.find_first_not_of('a');
Str.find_last_of("a");
// CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'find_last_of' called with a string
// CHECK-FIXES: Str.find_last_of('a');
Str.find_last_not_of("a");
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: 'find_last_not_of' called with a
// CHECK-FIXES: Str.find_last_not_of('a');
// std::wstring should work.
std::wstring WStr;
WStr.find(L"n");
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find(L'n');
// Even with unicode that fits in one wide char.
WStr.find(L"\x3A9");
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find(L'\x3A9');
// std::string_view and std::wstring_view should work.
std::string_view StrView;
StrView.find("n");
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'find' called with a string literal
// CHECK-FIXES: StrView.find('n');
std::wstring_view WStrView;
WStrView.find(L"n");
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'find' called with a string literal
// CHECK-FIXES: WStrView.find(L'n');
WStrView.find(L"\x3A9");
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'find' called with a string literal
// CHECK-FIXES: WStrView.find(L'\x3A9');
// Also with other types, but only if it was specified in the options.
llvm::StringRef sr;
sr.find("x");
// CHECK-MESSAGES-CUSTOM: [[@LINE-1]]:11: warning: 'find' called with a string literal
// CHECK-FIXES-CUSTOM: sr.find('x');
NotStringRef nsr;
nsr.find("x");
}
template <typename T>
int FindTemplateDependant(T value) {
return value.find("A");
}
template <typename T>
int FindTemplateNotDependant(T pos) {
return std::string().find("A", pos);
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string literal
// CHECK-FIXES: return std::string().find('A', pos);
}
int FindStr() {
return FindTemplateDependant(std::string()) + FindTemplateNotDependant(1);
}
#define STR_MACRO(str) str.find("A")
#define POS_MACRO(pos) std::string().find("A",pos)
int Macros() {
return STR_MACRO(std::string()) + POS_MACRO(1);
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'find' called with a string literal
// CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string literal
}