2016-02-13 03:28:14 +08:00
/ / RUN : % check_clang_tidy % s performance - faster - string - find % t - - \
/ / RUN : - config = " {CheckOptions: \
/ / RUN : [ { key : performance - faster - string - find . StringLikeClasses , \
// RUN: value: 'std::basic_string; ::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 ;
} // 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 " ) ;
2016-04-07 22:55:25 +08:00
// 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]
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find('a');
// Works with the pos argument.
Str . find ( " a " , 1 ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
// 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 " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.rfind('a');
Str . find_first_of ( " a " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'find_first_of' called with a string
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find_first_of('a');
Str . find_first_not_of ( " a " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:25: warning: 'find_first_not_of' called with a
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find_first_not_of('a');
Str . find_last_of ( " a " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'find_last_of' called with a string
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find_last_of('a');
Str . find_last_not_of ( " a " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: 'find_last_not_of' called with a
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find_last_not_of('a');
// std::wstring should work.
std : : wstring WStr ;
WStr . find ( L " n " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find(L'n');
// Even with unicode that fits in one wide char.
WStr . find ( L " \x3A9 " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: Str.find(L'\x3A9');
// Also with other types, but only if it was specified in the options.
llvm : : StringRef sr ;
sr . find ( " x " ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
// CHECK-FIXES: 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 ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
// 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 ) ;
2016-04-07 22:55:25 +08:00
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'find' called with a string literal
// CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string literal
2016-02-13 03:28:14 +08:00
}