Author: jonastoth Date: Wed Aug 30 06:32:05 2017 New Revision: 312122 URL: http://llvm.org/viewvc/llvm-project?rev=312122&view=rev Log: [clang-tidy] hicpp bitwise operations on signed integers
Summary: This check implements the rule [[ http://www.codingstandard.com/section/5-6-shift-operators/ | 5.6. HIC++ ]] that forbidds bitwise operations on signed integer types. Reviewers: aaron.ballman, hokein, alexfh, Eugene.Zelenko Reviewed By: aaron.ballman Subscribers: cfe-commits, mgorny, JDevlieghere, xazax.hun Differential Revision: https://reviews.llvm.org/D36586 Added: clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.cpp clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.h clang-tools-extra/trunk/docs/clang-tidy/checks/hicpp-signed-bitwise.rst clang-tools-extra/trunk/test/clang-tidy/hicpp-signed-bitwise.cpp Modified: clang-tools-extra/trunk/clang-tidy/hicpp/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/hicpp/HICPPTidyModule.cpp clang-tools-extra/trunk/docs/ReleaseNotes.rst clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Modified: clang-tools-extra/trunk/clang-tidy/hicpp/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/hicpp/CMakeLists.txt?rev=312122&r1=312121&r2=312122&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/hicpp/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/hicpp/CMakeLists.txt Wed Aug 30 06:32:05 2017 @@ -4,6 +4,7 @@ add_clang_library(clangTidyHICPPModule ExceptionBaseclassCheck.cpp NoAssemblerCheck.cpp HICPPTidyModule.cpp + SignedBitwiseCheck.cpp LINK_LIBS clangAST Modified: clang-tools-extra/trunk/clang-tidy/hicpp/HICPPTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/hicpp/HICPPTidyModule.cpp?rev=312122&r1=312121&r2=312122&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/hicpp/HICPPTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/hicpp/HICPPTidyModule.cpp Wed Aug 30 06:32:05 2017 @@ -26,6 +26,7 @@ #include "../readability/IdentifierNamingCheck.h" #include "ExceptionBaseclassCheck.h" #include "NoAssemblerCheck.h" +#include "SignedBitwiseCheck.h" namespace clang { namespace tidy { @@ -38,6 +39,8 @@ public: "hicpp-braces-around-statements"); CheckFactories.registerCheck<ExceptionBaseclassCheck>( "hicpp-exception-baseclass"); + CheckFactories.registerCheck<SignedBitwiseCheck>( + "hicpp-signed-bitwise"); CheckFactories.registerCheck<google::ExplicitConstructorCheck>( "hicpp-explicit-conversions"); CheckFactories.registerCheck<readability::FunctionSizeCheck>( Added: clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.cpp?rev=312122&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.cpp Wed Aug 30 06:32:05 2017 @@ -0,0 +1,56 @@ +//===--- SignedBitwiseCheck.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 "SignedBitwiseCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; +using namespace clang::ast_matchers::internal; + +namespace clang { +namespace tidy { +namespace hicpp { + +void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) { + const auto SignedIntegerOperand = + expr(ignoringImpCasts(hasType(isSignedInteger()))).bind("signed_operand"); + + // Match binary bitwise operations on signed integer arguments. + Finder->addMatcher( + binaryOperator(allOf(anyOf(hasOperatorName("|"), hasOperatorName("&"), + hasOperatorName("^"), hasOperatorName("<<"), + hasOperatorName(">>")), + hasEitherOperand(SignedIntegerOperand))) + .bind("binary_signed"), + this); + + // Match unary operations on signed integer types. + Finder->addMatcher(unaryOperator(allOf(hasOperatorName("~"), + hasUnaryOperand(SignedIntegerOperand))) + .bind("unary_signed"), + this); +} + +void SignedBitwiseCheck::check(const MatchFinder::MatchResult &Result) { + const ast_matchers::BoundNodes &N = Result.Nodes; + const auto *SignedBinary = N.getNodeAs<BinaryOperator>("binary_signed"); + const auto *SignedUnary = N.getNodeAs<UnaryOperator>("unary_signed"); + const auto *SignedOperand = N.getNodeAs<Expr>("signed_operand"); + + const bool IsUnary = SignedUnary != nullptr; + diag(IsUnary ? SignedUnary->getLocStart() : SignedBinary->getLocStart(), + "use of a signed integer operand with a %select{binary|unary}0 bitwise " + "operator") + << IsUnary << SignedOperand->getSourceRange(); +} + +} // namespace hicpp +} // namespace tidy +} // namespace clang Added: clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.h?rev=312122&view=auto ============================================================================== --- clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.h (added) +++ clang-tools-extra/trunk/clang-tidy/hicpp/SignedBitwiseCheck.h Wed Aug 30 06:32:05 2017 @@ -0,0 +1,36 @@ +//===--- SignedBitwiseCheck.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_HICPP_SIGNED_BITWISE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_SIGNED_BITWISE_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace hicpp { + +/// This check implements the rule 5.6.1 of the HICPP Standard, which disallows +/// bitwise operations on signed integer types. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/hicpp-signed-bitwise.html +class SignedBitwiseCheck : public ClangTidyCheck { +public: + SignedBitwiseCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace hicpp +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_SIGNED_BITWISE_H Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=312122&r1=312121&r2=312122&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed Aug 30 06:32:05 2017 @@ -120,6 +120,12 @@ Improvements to clang-tidy Ensures that all exception will be instances of ``std::exception`` and classes that are derived from it. +- New `hicpp-signed-bitwise + <http://clang.llvm.org/extra/clang-tidy/checks/hicpp-signed-bitwise.html>`_ check + + Finds uses of bitwise operations on signed integer types, which may lead to + undefined or implementation defined behaviour. + - New `android-cloexec-inotify-init1 <http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-inotify-init1.html>`_ check Added: clang-tools-extra/trunk/docs/clang-tidy/checks/hicpp-signed-bitwise.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/hicpp-signed-bitwise.rst?rev=312122&view=auto ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/hicpp-signed-bitwise.rst (added) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/hicpp-signed-bitwise.rst Wed Aug 30 06:32:05 2017 @@ -0,0 +1,9 @@ +.. title:: clang-tidy - hicpp-signed-bitwise + +hicpp-signed-bitwise +==================== + +Finds uses of bitwise operations on signed integer types, which may lead to +undefined or implementation defined behaviour. + +The according rule is defined in the `High Integrity C++ Standard, Section 5.6.1 <http://www.codingstandard.com/section/5-6-shift-operators/>`_. Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=312122&r1=312121&r2=312122&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Aug 30 06:32:05 2017 @@ -79,6 +79,7 @@ Clang-Tidy Checks hicpp-new-delete-operators (redirects to misc-new-delete-overloads) <hicpp-new-delete-operators> hicpp-no-assembler hicpp-noexcept-move (redirects to misc-noexcept-moveconstructor) <hicpp-noexcept-move> + hicpp-signed-bitwise hicpp-special-member-functions (redirects to cppcoreguidelines-special-member-functions) <hicpp-special-member-functions> hicpp-undelegated-constructor (redirects to misc-undelegated-constructor) <hicpp-undelegated-constructor> hicpp-use-equals-default (redirects to modernize-use-equals-default) <hicpp-use-equals-default> Added: clang-tools-extra/trunk/test/clang-tidy/hicpp-signed-bitwise.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/hicpp-signed-bitwise.cpp?rev=312122&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/hicpp-signed-bitwise.cpp (added) +++ clang-tools-extra/trunk/test/clang-tidy/hicpp-signed-bitwise.cpp Wed Aug 30 06:32:05 2017 @@ -0,0 +1,219 @@ +// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t + +// These could cause false positives and should not be considered. +struct StreamClass { +}; +StreamClass &operator<<(StreamClass &os, unsigned int i) { + return os; +} +StreamClass &operator<<(StreamClass &os, int i) { + return os; +} +StreamClass &operator>>(StreamClass &os, unsigned int i) { + return os; +} +StreamClass &operator>>(StreamClass &os, int i) { + return os; +} +struct AnotherStream { + AnotherStream &operator<<(unsigned char c) { return *this; } + AnotherStream &operator<<(char c) { return *this; } + + AnotherStream &operator>>(unsigned char c) { return *this; } + AnotherStream &operator>>(char c) { return *this; } +}; + +void binary_bitwise() { + int SValue = 42; + int SResult; + + unsigned int UValue = 42; + unsigned int UResult; + + SResult = SValue & 1; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + SResult = SValue & -1; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + SResult = SValue & SValue; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + + UResult = SValue & 1; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + UResult = SValue & -1; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + + UResult = UValue & 1u; // Ok + UResult = UValue & UValue; // Ok + + unsigned char UByte1 = 0u; + unsigned char UByte2 = 16u; + char SByte1 = 0; + char SByte2 = 16; + + UByte1 = UByte1 & UByte2; // Ok + UByte1 = SByte1 & UByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + UByte1 = SByte1 & SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + SByte1 = SByte1 & SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + + // More complex expressions. + UResult = UValue & (SByte1 + (SByte1 | SByte2)); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator + // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator + + // The rest is to demonstrate functionality but all operators are matched equally. + // Therefore functionality is the same for all binary operations. + UByte1 = UByte1 | UByte2; // Ok + UByte1 = UByte1 | SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + + UByte1 = UByte1 ^ UByte2; // Ok + UByte1 = UByte1 ^ SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + + UByte1 = UByte1 >> UByte2; // Ok + UByte1 = UByte1 >> SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + + UByte1 = UByte1 << UByte2; // Ok + UByte1 = UByte1 << SByte2; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator + + int SignedInt1 = 1 << 12; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator + int SignedInt2 = 1u << 12; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator +} + +void f1(unsigned char c) {} +void f2(char c) {} +void f3(int c) {} + +void unary_bitwise() { + unsigned char UByte1 = 0u; + char SByte1 = 0; + + UByte1 = ~UByte1; // Ok + SByte1 = ~UByte1; + SByte1 = ~SByte1; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator + UByte1 = ~SByte1; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator + + unsigned int UInt = 0u; + int SInt = 0; + + f1(~UByte1); // Ok + f1(~SByte1); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator + f1(~UInt); + f1(~SInt); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator + f2(~UByte1); + f2(~SByte1); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator + f2(~UInt); + f2(~SInt); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator + f3(~UByte1); // Ok + f3(~SByte1); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator +} + +/// HICPP uses these examples to demonstrate the rule. +void standard_examples() { + int i = 3; + unsigned int k = 0u; + + int r = i << -1; // Emits -Wshift-count-negative from clang + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator + r = i << 1; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + + r = -1 >> -1; // Emits -Wshift-count-negative from clang + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + r = -1 >> 1; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + + r = -1 >> i; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + r = -1 >> -i; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + + r = ~0; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator + r = ~0u; // Ok + k = ~k; // Ok + + unsigned int u = (-1) & 2u; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator + u = (-1) | 1u; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator + u = (-1) ^ 1u; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator +} + +void streams_should_work() { + StreamClass s; + s << 1u; // Ok + s << 1; // Ok + s >> 1; // Ok + s >> 1u; // Ok + + AnotherStream as; + unsigned char uc = 1u; + char sc = 1; + as << uc; // Ok + as << sc; // Ok + as >> uc; // Ok + as >> sc; // Ok +} + +enum OldEnum { + ValueOne, + ValueTwo, +}; + +enum OldSigned : int { + IntOne, + IntTwo, +}; + +void classicEnums() { + OldEnum e1 = ValueOne, e2 = ValueTwo; + int e3; // Using the enum type, results in an error. + e3 = ValueOne | ValueTwo; // Ok + e3 = ValueOne & ValueTwo; // Ok + e3 = ValueOne ^ ValueTwo; // Ok + e3 = e1 | e2; // Ok + e3 = e1 & e2; // Ok + e3 = e1 ^ e2; // Ok + + OldSigned s1 = IntOne, s2 = IntTwo; + int s3; + s3 = IntOne | IntTwo; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator + s3 = IntOne & IntTwo; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator + s3 = IntOne ^ IntTwo; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator + s3 = s1 | s2; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator + s3 = s1 & s2; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator + s3 = s1 ^ s2; // Signed + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator +} + +enum EnumConstruction { + one = 1, + two = 2, + test1 = 1 << 12, + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator + test2 = one << two, + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator + test3 = 1u << 12, + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits