Index: clang-tidy/misc/CMakeLists.txt =================================================================== --- clang-tidy/misc/CMakeLists.txt +++ clang-tidy/misc/CMakeLists.txt @@ -5,6 +5,7 @@ AssertSideEffectCheck.cpp MisplacedConstCheck.cpp UnconventionalAssignOperatorCheck.cpp + ComparisonMisuseCheck.cpp BoolPointerImplicitConversionCheck.cpp DanglingHandleCheck.cpp DefinitionsInHeadersCheck.cpp Index: clang-tidy/misc/ComparisonMisuseCheck.h =================================================================== --- /dev/null +++ clang-tidy/misc/ComparisonMisuseCheck.h @@ -0,0 +1,39 @@ +//===--- ComparisonMisuseCheck.h - clang-tidy--------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_COMPARISON_MISUSE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_COMPARISON_MISUSE_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace misc { + +/// This checker reports errors related to the misuse of the comparison operator. +/// It should warn for the following cases: +/// - strcmp,strncmp,memcmp misuse. +/// - char* is compared to a string literal +/// - inequality operator usage for NULL +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/misc-comparison-misuse.html +class ComparisonMisuseCheck : public ClangTidyCheck { +public: + ComparisonMisuseCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace misc +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_COMPARISON_MISUSE_H Index: clang-tidy/misc/ComparisonMisuseCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/misc/ComparisonMisuseCheck.cpp @@ -0,0 +1,52 @@ +//===--- ComparisonMisuseCheck.cpp - clang-tidy----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ComparisonMisuseCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace misc { + +void ComparisonMisuseCheck::registerMatchers(MatchFinder *Finder) { + + Finder->addMatcher( + binaryOperator(hasEitherOperand(ignoringImpCasts(stringLiteral())), + hasEitherOperand(hasType(pointsTo(isAnyCharacter())))) + .bind("charToLiteral"), + this); + + Finder->addMatcher( + binaryOperator( + unless(anyOf(hasOperatorName("=="), hasOperatorName("!="))), + hasEitherOperand(ignoringImpCasts(gnuNullExpr()))) + .bind("compareToNull"), + this); +} + +void ComparisonMisuseCheck::check(const MatchFinder::MatchResult &Result) { + const auto *CharToLiteral = + Result.Nodes.getNodeAs("charToLiteral"); + if (CharToLiteral) + diag(CharToLiteral->getOperatorLoc(), + "char* is compared to a string literal"); + + const auto *CompareToNull = + Result.Nodes.getNodeAs("compareToNull"); + if (CompareToNull) + diag(CompareToNull->getOperatorLoc(), "comparison to nullptr"); +} + +} // namespace misc +} // namespace tidy +} // namespace clang + Index: clang-tidy/misc/MiscTidyModule.cpp =================================================================== --- clang-tidy/misc/MiscTidyModule.cpp +++ clang-tidy/misc/MiscTidyModule.cpp @@ -15,6 +15,7 @@ #include "MisplacedConstCheck.h" #include "UnconventionalAssignOperatorCheck.h" #include "BoolPointerImplicitConversionCheck.h" +#include "ComparisonMisuseCheck.h" #include "DanglingHandleCheck.h" #include "DefinitionsInHeadersCheck.h" #include "FoldInitTypeCheck.h" @@ -68,6 +69,8 @@ "misc-unconventional-assign-operator"); CheckFactories.registerCheck( "misc-bool-pointer-implicit-conversion"); + CheckFactories.registerCheck( + "misc-comparison-misuse"); CheckFactories.registerCheck( "misc-dangling-handle"); CheckFactories.registerCheck( Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -55,6 +55,7 @@ misc-argument-comment misc-assert-side-effect misc-bool-pointer-implicit-conversion + misc-comparison-misuse misc-dangling-handle misc-definitions-in-headers misc-fold-init-type Index: docs/clang-tidy/checks/misc-comparison-misuse.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/misc-comparison-misuse.rst @@ -0,0 +1,25 @@ +.. title:: clang-tidy - misc-comparison-misuse + +misc-comparison-misuse +====================== + +This checker reports errors related to the misuse of the comparison operator. +It should warn for the following cases: + +Case 1: + ``char*`` is compared to a string literal. + +.. code-block:: + bool isMyString(const char * my){ + return "mystring"==my;//error. comparing pointer to string literal + } + + +Case 2: + Inequality operator usage for ``NULL``. + +.. code-block:: c++ + void(int * p){ + if (NULL>=p)//error, use only NULL==p, NULL!=p + } + Index: test/clang-tidy/misc-comparison-misuse.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc-comparison-misuse.cpp @@ -0,0 +1,20 @@ +// RUN: %check_clang_tidy %s misc-comparison-misuse %t + +#define NULL __null + +bool test_pointer_to_literal(const char *my){ + bool b = (my=="mystring"); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: char* is compared to a string literal [misc-comparison-misuse] + return "mystring"==my; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: char* is compared to a string literal [misc-comparison-misuse] +} + +void test_null_to_pointer(int *p){ + if (NULL>=p); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: comparison to nullptr [misc-comparison-misuse] + + if (NULL==p); + + if (NULL!=p); +} +