llvm-project
57 строк · 2.0 Кб
1//===--- IncorrectRoundingsCheck.cpp - clang-tidy ------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "IncorrectRoundingsCheck.h"10#include "clang/AST/DeclBase.h"11#include "clang/AST/Type.h"12#include "clang/ASTMatchers/ASTMatchFinder.h"13#include "clang/ASTMatchers/ASTMatchers.h"14#include "clang/Lex/Lexer.h"15
16using namespace clang::ast_matchers;17
18namespace clang::tidy::bugprone {19
20static llvm::APFloat getHalf(const llvm::fltSemantics &Semantics) {21return llvm::APFloat(Semantics, 1U) / llvm::APFloat(Semantics, 2U);22}
23
24namespace {25AST_MATCHER(FloatingLiteral, floatHalf) {26return Node.getValue() == getHalf(Node.getSemantics());27}
28} // namespace29
30void IncorrectRoundingsCheck::registerMatchers(MatchFinder *MatchFinder) {31// Match a floating literal with value 0.5.32auto FloatHalf = floatLiteral(floatHalf());33
34// Match a floating point expression.35auto FloatType = expr(hasType(realFloatingPointType()));36
37// Find expressions of cast to int of the sum of a floating point expression38// and 0.5.39MatchFinder->addMatcher(40traverse(TK_AsIs,41implicitCastExpr(42hasImplicitDestinationType(isInteger()),43ignoringParenCasts(binaryOperator(44hasOperatorName("+"), hasOperands(FloatType, FloatType),45hasEitherOperand(ignoringParenImpCasts(FloatHalf)))))46.bind("CastExpr")),47this);48}
49
50void IncorrectRoundingsCheck::check(const MatchFinder::MatchResult &Result) {51const auto *CastExpr = Result.Nodes.getNodeAs<ImplicitCastExpr>("CastExpr");52diag(CastExpr->getBeginLoc(),53"casting (double + 0.5) to integer leads to incorrect rounding; "54"consider using lround (#include <cmath>) instead");55}
56
57} // namespace clang::tidy::bugprone58