forked from OSchip/llvm-project
140 lines
4.6 KiB
C++
140 lines
4.6 KiB
C++
// 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
|
|
}
|