1 //===--- IntegerDivisionCheck.cpp - clang-tidy-----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "IntegerDivisionCheck.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 14 using namespace clang::ast_matchers; 15 16 namespace clang { 17 namespace tidy { 18 namespace bugprone { 19 20 void IntegerDivisionCheck::registerMatchers(MatchFinder *Finder) { 21 const auto IntType = hasType(isInteger()); 22 23 const auto BinaryOperators = binaryOperator(anyOf( 24 hasOperatorName("%"), hasOperatorName("<<"), hasOperatorName(">>"), 25 hasOperatorName("<<"), hasOperatorName("^"), hasOperatorName("|"), 26 hasOperatorName("&"), hasOperatorName("||"), hasOperatorName("&&"), 27 hasOperatorName("<"), hasOperatorName(">"), hasOperatorName("<="), 28 hasOperatorName(">="), hasOperatorName("=="), hasOperatorName("!="))); 29 30 const auto UnaryOperators = 31 unaryOperator(anyOf(hasOperatorName("~"), hasOperatorName("!"))); 32 33 const auto Exceptions = 34 anyOf(BinaryOperators, conditionalOperator(), binaryConditionalOperator(), 35 callExpr(IntType), explicitCastExpr(IntType), UnaryOperators); 36 37 Finder->addMatcher( 38 binaryOperator( 39 hasOperatorName("/"), hasLHS(expr(IntType)), hasRHS(expr(IntType)), 40 hasAncestor( 41 castExpr(hasCastKind(CK_IntegralToFloating)).bind("FloatCast")), 42 unless(hasAncestor( 43 expr(Exceptions, 44 hasAncestor(castExpr(equalsBoundNode("FloatCast"))))))) 45 .bind("IntDiv"), 46 this); 47 } 48 49 void IntegerDivisionCheck::check(const MatchFinder::MatchResult &Result) { 50 const auto *IntDiv = Result.Nodes.getNodeAs<BinaryOperator>("IntDiv"); 51 diag(IntDiv->getBeginLoc(), "result of integer division used in a floating " 52 "point context; possible loss of precision"); 53 } 54 55 } // namespace bugprone 56 } // namespace tidy 57 } // namespace clang 58