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
}
|