void IncorrectRoundings::registerMatchers(MatchFinder *MatchFinder) { // Match a floating literal with value 0.5. auto FloatHalf = floatLiteral(floatHalf()); // Match a floating point expression. auto FloatType = expr(hasType(realFloatingPointType())); // Match a floating literal of 0.5 or a floating literal of 0.5 implicitly. // cast to floating type. auto FloatOrCastHalf = anyOf(FloatHalf, implicitCastExpr(FloatType, has(FloatHalf))); // Match if either the LHS or RHS is a floating literal of 0.5 or a floating // literal of 0.5 and the other is of type double or vice versa. auto OneSideHalf = anyOf(allOf(hasLHS(FloatOrCastHalf), hasRHS(FloatType)), allOf(hasRHS(FloatOrCastHalf), hasLHS(FloatType))); // Find expressions of cast to int of the sum of a floating point expression // and 0.5. MatchFinder->addMatcher( implicitCastExpr( hasImplicitDestinationType(isInteger()), ignoringParenCasts(binaryOperator(hasOperatorName("+"), OneSideHalf))) .bind("CastExpr"), this); }
llvm::Optional<std::string> stripFloatCast(const ast_matchers::MatchFinder::MatchResult &Result, const Expr &Node) { if (const Expr *MaybeCastArg = selectFirst<const Expr>( "cast_arg", match(expr(anyOf(cxxStaticCastExpr( hasDestinationType(realFloatingPointType()), hasSourceExpression(expr().bind("cast_arg"))), cStyleCastExpr( hasDestinationType(realFloatingPointType()), hasSourceExpression(expr().bind("cast_arg"))), cxxFunctionalCastExpr( hasDestinationType(realFloatingPointType()), hasSourceExpression(expr().bind("cast_arg"))))), Node, *Result.Context))) return tooling::fixit::getText(*MaybeCastArg, *Result.Context).str(); return llvm::None; }
/// Returns `true` if `Node` is a value which evaluates to a literal `0`. bool IsLiteralZero(const MatchFinder::MatchResult &Result, const Expr &Node) { auto ZeroMatcher = anyOf(integerLiteral(equals(0)), floatLiteral(equals(0.0))); // Check to see if we're using a zero directly. if (selectFirst<const clang::Expr>( "val", match(expr(ignoringImpCasts(ZeroMatcher)).bind("val"), Node, *Result.Context)) != nullptr) return true; // Now check to see if we're using a functional cast with a scalar // initializer expression, e.g. `int{0}`. if (selectFirst<const clang::Expr>( "val", match(cxxFunctionalCastExpr( hasDestinationType( anyOf(isInteger(), realFloatingPointType())), hasSourceExpression(initListExpr( hasInit(0, ignoringParenImpCasts(ZeroMatcher))))) .bind("val"), Node, *Result.Context)) != nullptr) return true; return false; }
void FloatLoopCounter::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( forStmt(hasIncrement(expr(hasType(realFloatingPointType())))).bind("for"), this); }