Skip to content

Commit

Permalink
Expand localized sorting to cover pair, tuple
Browse files Browse the repository at this point in the history
Warn about comparison or sorting of pairs or tuples where one of the
elements is a string.
  • Loading branch information
jbytheway committed May 7, 2020
1 parent 274e82e commit 9916cf2
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 4 deletions.
48 changes: 44 additions & 4 deletions tools/clang-tidy-plugin/UseLocalizedSortingCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,54 @@ namespace tidy
namespace cata
{

inline bool IsString( QualType T )
static bool IsStringish( QualType T );

static bool IsStringish( const TemplateArgument &Arg )
{
switch( Arg.getKind() ) {
case TemplateArgument::Type:
if( IsStringish( Arg.getAsType() ) ) {
return true;
}
break;
case TemplateArgument::Pack:
for( const TemplateArgument &PackArg : Arg.getPackAsArray() ) {
if( IsStringish( PackArg ) ) {
return true;
}
}
break;
default:
break;
}
return false;
}

static bool IsStringish( QualType T )
{
const TagDecl *TTag = T.getTypePtr()->getAsTagDecl();
if( !TTag ) {
return false;
}
StringRef Name = TTag->getName();
return Name == "basic_string";
if( Name == "basic_string" ) {
return true;
}
if( Name == "pair" || Name == "tuple" ) {
const ClassTemplateSpecializationDecl *SpecDecl =
dyn_cast<ClassTemplateSpecializationDecl>( TTag );
if( !SpecDecl ) {
fprintf( stderr, "Not a spec: %s\n", TTag->getKindName().str().c_str() );
return false;
}
const TemplateArgumentList &Args = SpecDecl->getTemplateArgs();
for( const TemplateArgument &Arg : Args.asArray() ) {
if( IsStringish( Arg ) ) {
return true;
}
}
}
return false;
}

void UseLocalizedSortingCheck::registerMatchers( MatchFinder *Finder )
Expand Down Expand Up @@ -81,7 +121,7 @@ static void CheckOpCall( UseLocalizedSortingCheck &Check, const MatchFinder::Mat
return;
}

if( !IsString( *Arg0Type ) ) {
if( !IsStringish( *Arg0Type ) ) {
return;
}

Expand Down Expand Up @@ -123,7 +163,7 @@ static void CheckSortCall( UseLocalizedSortingCheck &Check, const MatchFinder::M
ValueType = *BoundValueType;
}

if( !IsString( ValueType ) ) {
if( !IsStringish( ValueType ) ) {
return;
}

Expand Down
41 changes: 41 additions & 0 deletions tools/clang-tidy-plugin/test/use-localized-sorting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ bool operator<( const std::basic_string<CharT, Traits, Alloc> &lhs,
template<class RandomIt>
void sort( RandomIt first, RandomIt last );

template<class T1, class T2>
struct pair;

template< class T1, class T2 >
bool operator<( const std::pair<T1, T2> &lhs, const std::pair<T1, T2> &rhs );

template< class... Types >
class tuple;

template<class... TTypes, class... UTypes>
bool operator<( const tuple<TTypes...> &lhs,
const tuple<UTypes...> &rhs );
}

template<class T>
Expand All @@ -48,6 +60,35 @@ bool f1( const NonString &l, const NonString &r )
return l < r;
}

bool f2( const std::pair<int, std::string> &l, const std::pair<int, std::string> &r )
{
return l < r;
// CHECK-MESSAGES: warning: Raw comparison of 'const std::pair<int, std::string>' (aka 'const pair<int, basic_string<char> >'). For UI purposes please use localized_compare from translations.h. [cata-use-localized-sorting]
}

bool f3( const std::pair<int, NonString> &l, const std::pair<int, NonString> &r )
{
return l < r;
}

bool f4( const std::tuple<int, std::string> &l, const std::tuple<int, std::string> &r )
{
return l < r;
// CHECK-MESSAGES: warning: Raw comparison of 'const std::tuple<int, std::string>' (aka 'const tuple<int, basic_string<char> >'). For UI purposes please use localized_compare from translations.h. [cata-use-localized-sorting]
}

bool f5( const std::tuple<int, NonString> &l, const std::tuple<int, NonString> &r )
{
return l < r;
}

bool f4( const std::tuple<std::tuple<std::string>> &l,
const std::tuple<std::tuple<std::string>> &r )
{
return l < r;
// CHECK-MESSAGES: warning: Raw comparison of 'const std::tuple<std::tuple<std::string> >' (aka 'const tuple<tuple<basic_string<char> > >'). For UI purposes please use localized_compare from translations.h. [cata-use-localized-sorting]
}

bool sort0( const std::string *start, const std::string *end )
{
std::sort( start, end );
Expand Down

0 comments on commit 9916cf2

Please sign in to comment.